# sugar for flatMap

4 replies
Jeff Olson
Joined: 2011-06-29,
Am I correct in assuming that there is no convenient for-comprehension sugar for expr.flatMap(x => f(x)) ?

One might think that the following would work:

for(x <- expr; y <- f(x)) yield y

but technically this desugars to

expr.flatMap(x => f(x).map(y => y))

Now if we can assume that map on f(x) is a proper functor (i.e. map(y => y) is a no-op), then this is just expr.flatMap(x => f(x)) as desired. But I'm assuming that scala makes no such assumptions about map and blindly executes it.
dcsobral
Joined: 2009-04-23,
Re: sugar for flatMap

On Thu, Aug 4, 2011 at 15:29, Jeff Olson wrote:
> Am I correct in assuming that there is no convenient for-comprehension sugar
> for expr.flatMap(x => f(x)) ?
>
> One might think that the following would work:
>
> for(x <- expr; y <- f(x)) yield y
>
> but technically this desugars to
>
> expr.flatMap(x => f(x).map(y => y))
>
> Now if we can assume that map on f(x) is a proper functor (i.e. map(y => y)
> is a no-op), then this is just expr.flatMap(x => f(x)) as desired. But I'm
> assuming that scala makes no such assumptions about map and blindly executes
> it.

I have toyed before with the suggestion that if a for expression is of
the form "yield x", where "x" is the last generator, then the map
should be omitted.

Sebastien Bocq
Joined: 2008-12-18,
Re: sugar for flatMap

2011/8/4 Jeff Olson <jdolson [at] rgmadvisors [dot] com>
Am I correct in assuming that there is no convenient for-comprehension sugar for expr.flatMap(x => f(x)) ?

One might think that the following would work:

for(x <- expr; y <- f(x)) yield y

but technically this desugars to

expr.flatMap(x => f(x).map(y => y))

Now if we can assume that map on f(x) is a proper functor (i.e. map(y => y) is a no-op), then this is just expr.flatMap(x => f(x)) as desired. But I'm assuming that scala makes no such assumptions about map and blindly executes it.

for (e1)
=> e1

for (e1; e2; ...; en)
=> e1.flatMap(_ => for(e2; ...; en))

for (pat <- e1; e2; ...; en)
=> e1.flatMap(pat => for(e2; ...; en))

You could then simply write:
for(x <- expr1; f(x))

What is the rationale behind the current implementation? Would there be an ambiguity with yield or foreach forms?

Thanks,
Sébastien
milessabin
Joined: 2008-08-11,
Re: sugar for flatMap

On Thu, Aug 4, 2011 at 7:29 PM, Jeff Olson wrote:
> Am I correct in assuming that there is no convenient for-comprehension sugar
> for expr.flatMap(x => f(x)) ?
>
> One might think that the following would work:
>
> for(x <- expr; y <- f(x)) yield y
>
> but technically this desugars to
>
> expr.flatMap(x => f(x).map(y => y))
>
> Now if we can assume that map on f(x) is a proper functor (i.e. map(y => y)
> is a no-op), then this is just expr.flatMap(x => f(x)) as desired. But I'm
> assuming that scala makes no such assumptions about map and blindly executes
> it.

That's correct.

Looking on the bright side, you can exploit this behaviour to get the
result you want,

scala> case class fakeFunctor[T](t : T) { def map(f : T => T) = t }
defined class fakeFunctor

scala> def f[T](t : T) = List(t)
f: [T](t: T)List[T]

scala> for (x <- 0 until 3 ; y <- fakeFunctor(f(x))) yield y
res1: scala.collection.immutable.IndexedSeq[Int] = Vector(0, 1, 2)

List.map won't be called here.

Cheers,

Miles

Cibor
Joined: 2011-05-03,
REMOVE ME

----------------------------------------------------------------
Zmyslowa bielizna? U nas ja znajdziesz!