Reputation: 16251
Is there a "for" syntax for
c flatmap ( x => d flatmap (y => f(x,y) ) )
?
Because I've used Haskell in the past, I keep expecting the "for" syntax in Scala to mimic the "do" syntax of Haskell. This is probably an unrealistic expectation. In Haskell which I could write
do x <- c
y <- d
f(x, y)
Upvotes: 1
Views: 138
Reputation: 9820
You could also map the last result on itself.
Using the same example as 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)
Which corresponds to:
c flatMap ( x => d flatMap (y => f(x,y) map (identity) ) )
Upvotes: 4
Reputation: 692
Flattening may impact performance but i think scalac is clever enough to encode
for {
x <- c
y <- d
z <- f(x,y)
} yield z
into
c flatMap { x => d flatMap { y => f(x,y) } }
This is annoying that the 'for' syntax is not as convenient as the 'do'-notation (writing _ <- someExpression
instead of just someExpression
in a for feels my heart with sadness).
Upvotes: 3
Reputation: 52701
You can just flatten the result:
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)
Presumably this is a much less frequently used case since it is necessarily less common that the output of the for
is flattenable. And sticking .flatten
on the end is pretty easy, so having a special syntax for it seems unnecessarily complicated.
Upvotes: 3