1) 虽然看过不少FP的东西,但是有一天碰到一个操作,还是没有搞清楚用map与flatmap的区别何在。举一个浅显的栗子:
map出来的结果很显而易见,为什么flatMap的结果却是List[Char]?
简单看下实现去:
还记得FP里面的functor和monad分别对应map与flatMap。
functor:F[A] A ->B => F[B] 就是想要A的包装类型F[A]转化成B的包装类型F[B]时,你只需要传一个A类型到B类型的转化函数。
monad: F[A] A ->F[B] => F[B]
同样,单子monad的范式就是想要A的包装类型F[A]转化成B的包装类型F[B]时,你只需要传一个A类型到F[B]类型的包装类型的转化函数。
再结合上面的源码就一目了然了。map传入的函数返回时B类型。flatMap传入函数的返回值是GenTraversableOnce(直接继承Any的高级抽象类型)集合类型。显然B类型跟GenTraversableOnce的范畴都不一样。
再回答下为什么是List[Char],很简单,flatMap里面有一步f(rest.head).seq即String.seq操作,所以结果是Char.
OK.再看个例子,
List(11,22,33).flatMap(Some(_))
返回应该是List(Some(11),Some(22),Some(33)么?
但是flatMap的作用不是压平集合么? 肯定不对。真正的结果是List(11,22,33)。至于为什么结果不变,解释跟上面一样。
但是上面说flatMap传入的函数应该是返回GenTraversableOnce的集合类型,Some明显不对啊。第一反应想到的肯定是Some在哪里被隐式转换掉了。
果然: