scala: map與flatmap的區(qū)別

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)換掉了。

果然:?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容