1) 雖然看過不少FP的東西工坊,但是有一天碰到一個操作献汗,還是沒有搞清楚用map與flatmap的區(qū)別何在。舉一個淺顯的栗子:
map出來的結(jié)果很顯而易見王污,為什么flatMap的結(jié)果卻是List[Char]?
簡單看下實(shí)現(xiàn)去:
還記得FP里面的functor和monad分別對應(yīng)map與flatMap罢吃。
functor:F[A] A ->B => F[B] 就是想要A的包裝類型F[A]轉(zhuǎn)化成B的包裝類型F[B]時,你只需要傳一個A類型到B類型的轉(zhuǎn)化函數(shù)昭齐。
monad: F[A] A ->F[B] => F[B]?
同樣尿招,單子monad的范式就是想要A的包裝類型F[A]轉(zhuǎn)化成B的包裝類型F[B]時,你只需要傳一個A類型到F[B]類型的包裝類型的轉(zhuǎn)化函數(shù)阱驾。
再結(jié)合上面的源碼就一目了然了就谜。map傳入的函數(shù)返回時B類型。flatMap傳入函數(shù)的返回值是GenTraversableOnce(直接繼承Any的高級抽象類型)集合類型里覆。顯然B類型跟GenTraversableOnce的范疇都不一樣丧荐。
再回答下為什么是List[Char],很簡單喧枷,flatMap里面有一步f(rest.head).seq即String.seq操作篮奄,所以結(jié)果是Char.
OK.再看個例子,
List(11,22,33).flatMap(Some(_))
返回應(yīng)該是List(Some(11),Some(22),Some(33)么?
但是flatMap的作用不是壓平集合么? 肯定不對割去。真正的結(jié)果是List(11,22,33)窟却。至于為什么結(jié)果不變,解釋跟上面一樣呻逆。
但是上面說flatMap傳入的函數(shù)應(yīng)該是返回GenTraversableOnce的集合類型夸赫,Some明顯不對啊。第一反應(yīng)想到的肯定是Some在哪里被隱式轉(zhuǎn)換掉了咖城。
果然:?