1) 雖然看過(guò)不少FP的東西,但是有一天碰到一個(gè)操作,還是沒(méi)有搞清楚用map與flatmap的區(qū)別何在。舉一個(gè)淺顯的栗子:

map出來(lái)的結(jié)果很顯而易見(jiàn),為什么flatMap的結(jié)果卻是List[Char]?
簡(jiǎn)單看下實(shí)現(xiàn)去:


還記得FP里面的functor和monad分別對(duì)應(yīng)map與flatMap。
functor:F[A] A ->B => F[B] 就是想要A的包裝類型F[A]轉(zhuǎn)化成B的包裝類型F[B]時(shí),你只需要傳一個(gè)A類型到B類型的轉(zhuǎn)化函數(shù)。
monad: F[A] A ->F[B] => F[B]?
同樣,單子monad的范式就是想要A的包裝類型F[A]轉(zhuǎn)化成B的包裝類型F[B]時(shí),你只需要傳一個(gè)A類型到F[B]類型的包裝類型的轉(zhuǎn)化函數(shù)。
再結(jié)合上面的源碼就一目了然了。map傳入的函數(shù)返回時(shí)B類型。flatMap傳入函數(shù)的返回值是GenTraversableOnce(直接繼承Any的高級(jí)抽象類型)集合類型。顯然B類型跟GenTraversableOnce的范疇都不一樣。
再回答下為什么是List[Char],很簡(jiǎn)單,flatMap里面有一步f(rest.head).seq即String.seq操作,所以結(jié)果是Char.
OK.再看個(gè)例子,
List(11,22,33).flatMap(Some(_))
返回應(yīng)該是List(Some(11),Some(22),Some(33)么?
但是flatMap的作用不是壓平集合么? 肯定不對(duì)。真正的結(jié)果是List(11,22,33)。至于為什么結(jié)果不變,解釋跟上面一樣。
但是上面說(shuō)flatMap傳入的函數(shù)應(yīng)該是返回GenTraversableOnce的集合類型,Some明顯不對(duì)啊。第一反應(yīng)想到的肯定是Some在哪里被隱式轉(zhuǎn)換掉了。
果然:?
