将Curried函数从flatMap转换为for-expression

时间:2014-01-06 14:24:01

标签: scala

我使用flatMap成功实现了以下curried函数:

  def map3(a: Option[Int], b: Option[Int], c: Option[Int])
(f: (Int, Int, Int) => Option[Int]): Option[Int] = {
    a.flatMap(x => b.flatMap(y => c.flatMap(z => f(x,y,z) ) ) )
  }

示例:

scala> map3(Some(1), Some(2), Some(3))( (x,y,z) => Some(x*y*z) )
res0: Option[Int] = Some(6)

但是,当我尝试使用for expression

实现相同的功能时
  def map3ForExpr(a: Option[Int], b: Option[Int], c: Option[Int])
(f: (Int, Int, Int) => Option[Int]): Option[Int] = {
    for { 
        x <- a
        y <- b
        z <- b
        f(x,y,z)
    }
  }  

...发生以下编译时错误:

  

C:\用户\凯文\工作区\侧工作&GT; scalac   TestForComprehensionMap3.scala TestForComprehensionMap3.scala:13:   错误:'&lt; - '预期,但'}'找到了。           }           ^

在阅读此优秀post的基础上,我觉得我的map3ForExpr等同于我的map3代码。

请让我知道我做错了什么。

1 个答案:

答案 0 :(得分:2)

凯文,你必须从for-comprehension中返回一些内容:

 for{
   x <- a
   y <- b
   z <- c
   out <- f(x, y, z)
 } yield out

也就是说,它需要知道mapflatMap的内容以及需要yeild表达式才能返回值。如果没有yield,你最终会遇到一个被贬低的foreach

另外,如果您只是yield f(x, y, z)而不是首先将其解压缩到out,那么您需要添加Option[Option[Int]]不是你想要的。