Higher-Order Functions & For-Comprehensions
Any type with map, flatMap, (withFilter), (foreach) works in for-comprehensions: Option, Either, Try, Future, IO, parsers, your own types.
18.1 For-comprehensions desugar to map/flatMap/withFilter
Any type with map, flatMap, (withFilter), (foreach) works in for-comprehensions: Option, Either, Try, Future, IO, parsers, your own types.
for
x <- List(1, 2, 3)
y <- List("a", "b")
if x > 1
yield (x, y)
// is translated to
List(1, 2, 3).withFilter(_ > 1).flatMap(x => List("a", "b").map(y => (x, y)))18.2 Mixing generators and definitions
All generators must be the same "container" type (you can't mix Option and List without conversion).
for
user <- findUser(id) // Option[User]
name = user.name.trim // plain value binding
email <- user.email // Option[String]
yield s"$name <$email>"18.3 Writing your own monadic type
case class Box[A](value: A):
def map[B](f: A => B): Box[B] = Box(f(value))
def flatMap[B](f: A => Box[B]): Box[B] = f(value)
for a <- Box(1); b <- Box(2) yield a + b // Box(3)18.4 Function-returning functions & currying in practice
def filterBy[A](pred: A => Boolean)(xs: List[A]): List[A] = xs.filter(pred)
val positives = filterBy[Int](_ > 0)
positives(List(-1, 2, 3))