From: Florian Gilcher on

On Apr 15, 2010, at 1:06 PM, Intransition wrote:

> First a big shout-out to Marc-Andre Lafortune and his <a href="http://
> github.com/marcandre/backports">backports</a> project. Nice work.
>
> Now I want to ask if others have noticed all the new methods being add
> to 1.9+? I'm quite happy about vast majority of it, but there was at
> least one method I thought pretty peculiar. This Enumerable method:
>
> def flat_map(&block)
> return to_enum(:flat_map) unless block_given?
> map(&block).flatten(1)
> end unless method_defined? :flat_map
> Backports.alias_method self, :collect_concat, :flat_map
>
> I am very curious to know how it was decided that a normal map
> followed by a 1-deep flatten is common enough to warrant its own
> method? Two in fact!
>

One advantage of :flat_map over map(...).flatten(...) is that it can be chained in an Enumerator.

Sometimes, this can come in handy.

Regards,
Florian Gilcher


From: Ryan Davis on

On Apr 15, 2010, at 06:34 , James Edward Gray II wrote:

> On Apr 15, 2010, at 6:30 AM, Ryan Davis wrote:
>
>> i use Hash[*collection.map {...}.flatten] all the time.
>
> Me too, but it's needed less in 1.9 I think. Hash[…] now accepts an Array of Arrays.

nice. too bad I don't use 1.9 at all.


From: Jörg W Mittag on
Intransition wrote:
> First a big shout-out to Marc-Andre Lafortune and his <a href="http://
> github.com/marcandre/backports">backports</a> project. Nice work.
>
> Now I want to ask if others have noticed all the new methods being add
> to 1.9+? I'm quite happy about vast majority of it, but there was at
> least one method I thought pretty peculiar. This Enumerable method:
>
> def flat_map(&block)
> return to_enum(:flat_map) unless block_given?
> map(&block).flatten(1)
> end unless method_defined? :flat_map
> Backports.alias_method self, :collect_concat, :flat_map
>
> I am very curious to know how it was decided that a normal map
> followed by a 1-deep flatten is common enough to warrant its own
> method? Two in fact!

#flat_map is monadic bind (also known as flatMap in Scala, SelectMany
in .NET and (>>=) in Haskell). The other monadic operator that is
needed to build a monad, is unit (aka return in Haskell), but in an OO
language, that's just a factory method, IOW it's just .new in Ruby.

So, #flat_map can potentially turn any class that mixes in Enumerable
into a monad, provided that it also obeys the monad laws, of course.

Whether or not that warrants its own method ... well, I have no idea.

jwm