for-comprehensions 是最终会编译成 map
和flatMap
的语法糖
如果一个类 有实现def map[B](f: A => B): 类名[B]
这个map方法
就可以用一行的for表达式表示这个map方法的调用, 如
sealed trait Option[+A] {
def map[B](f: A => B): Option[B] = {
this match {
case None=>None
case Some(a)=>Some(f(a))
}
}
//其他方法
}
就可以这样用
for {
a1 <- Some(a)
} yield f(a1)
// f是某A=>B的函数
会被编译成
Some(a).map(a1=>f(a1))
返回值是 Option[B]
如果同时实现了 方法 def map[B](f: A => B): 类名[B]
和 def flatMap[B](f: A => 类名[B]): 类名[B]
如Option
sealed trait Option[+A] {
def map[B](f: A => B): Option[B] = {
this match {
case None=>None
case Some(a)=>Some(f(a))
}
}
def flatMap[B](f: A => Option[B]): Option[B] = {
this match {
case None=>None
case Some(a)=>f(a)
}
}
//其他方法
}
就可以这样, 用多行绑定的for表达式
def map2[A,B,C](a: Option[A], b: Option[B])(f: (A, B) => C): Option[C] ={
for{
p1<- a
p2<- b
}yield{
f(p1,p2)
}
里面这个for表达式会被编译成a.flatMap(aa => b map (bb => f(aa, bb)))
再比如 Either
sealed trait Either[+E,+A] {
def map[B](f: A => B): Either[E, B] =
this match {
case Right(a) => Right(f(a))
case Left(e) => Left(e)
}
def flatMap[EE >: E, B](f: A => Either[EE, B]): Either[EE, B] =
this match {
case Left(e) => Left(e)
case Right(a) => f(a)
}
// 其他函数
}
可以这样用
for {
age <- Right(42)
name <- Left("invalid name")
salary <- Right(1000000.0)
} yield employee(name, age, salary)
返回值类型是 Either[String,Employee]
, 如果其他行也有Left 并且是其他类型的E, String 可以提示类型到Any
网友评论