for-comprehensions(gold_axe)

2019-05-22  本文已影响0人  胖达_4b7e

for-comprehensions 是最终会编译成 mapflatMap的语法糖
如果一个类 有实现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

上一篇下一篇

猜你喜欢

热点阅读