是否有" for" flatmap的语法?

时间:2015-06-24 18:03:17

标签: scala

是否有" for"

的语法
c flatmap ( x => d flatmap (y => f(x,y) ) )

因为我过去曾使用Haskell,所以我一直期待" for" Scala中的语法模仿" do" Haskell的语法。这可能是一个不切实际的期望。在Haskell,我可以写

do x <- c
   y <- d
   f(x, y)

3 个答案:

答案 0 :(得分:4)

您还可以将最后的结果映射到自身。

使用与dhg:

相同的示例
val c = 1 to 3
val d = 4 to 6
def f(x: Int, y: Int) = Vector(x,y)

for { 
  x <- c
  y <- d
  z <- f(x,  y) 
} yield z
// Vector(1, 4, 1, 5, 1, 6, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6)

对应于:

c flatMap ( x => d flatMap (y => f(x,y) map (identity) ) )

答案 1 :(得分:3)

你可以简化结果:

val c = 1 to 3
val d = 4 to 6
def f(x: Int, y: Int) = Vector(x,y)

c flatMap ( x => d flatMap (y => f(x,y) ) )
// Vector(1, 4, 1, 5, 1, 6, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6)

(for { x <- c; y <- d } yield f(x,y)).flatten
// Vector(1, 4, 1, 5, 1, 6, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6)

据推测,这是一个不太常用的案例,因为for的输出必须是平坦的,这一点不太常见。并且坚持.flatten非常简单,因此使用特殊语法似乎不必要地复杂。

答案 2 :(得分:3)

展平可能会影响性能但我认为scalac足够聪明来编码

for {
  x <- c
  y <- d
  z <- f(x,y)
} yield z

c flatMap { x => d flatMap { y => f(x,y) } }

令人讨厌的是&#39; for&#39;语法不像&#39; do&#39; -notation(写_ <- someExpression而不仅仅是someExpression而感觉到我的内心悲伤)。