[英]fmap and “flat map” in Haskell
所有這一次,當任何Haskell演講中談到“平面地圖”時,通常與Monads有關,我認為它被稱為“平面”,原因是它平坦了容器。 所以
[[1,2],[3,4]]
將被處理就像它一樣
[1,2,3,4]
但是現在我發現fmap和map基本上是一回事,唯一的區別是一個用於仿函數而另一個用於just列表。 最后,這只是在使用map時避免混淆錯誤消息。
真的嗎? 如果是這樣,為什么fmap中的f
意味着“平坦”,為什么不是“functor map”?
如果是這樣,為什么
fmap
f
意味着“平坦”,為什么不是“functor map”?
你的直覺是對的: fmap
中的f
代表“functor map”,而不是“flat map”。 事實上,在較新的類似語言中,例如PureScript,名稱只是map
。 不過,Haskell map
首先是為列表定義的,所以提出一個新名稱很困難。 使用Functor中的F是一個簡單的(如果不是特別有創意的話)選擇。
講師更可能是指monadic綁定函數, >>=
。 由於x >>= f
等於join (fmap fx)
,bind在其他語言中有時也稱為flatMap
。 它具有您在列表中所期望的行為,例如:
> [1,2,3] >>= \x -> [x,x]
[1,1,2,2,3,3]
但是,請記住,這個“平面地圖”不會遞歸地變平到任意深度,這一點很重要。 實際上,如果沒有復雜的類型類技巧,在Haskell中編寫這樣的函數實際上是不可能的。 自己嘗試一下: flatten
函數的類型簽名是什么樣的,甚至是直接在列表上運行的?
flatten :: ??? -> [a]
相比, >>=
函數非常簡單:它就像fmap
一樣,但是每個輸出元素都必須包含在fmap
函數中,並且>>=
淺淺地將結果“展平”成一個包裝器。 這個操作是monad的本質,這就是為什么>>=
函數存在於Monad
類型類中,但fmap
在Functor
。
這個答案來自原始問題的一些評論,因此我將其標記為社區維基。 歡迎編輯和改進。
以下是一些如何在Haskell中執行flatMap
明確等效示例。
Prelude> map (replicate 3) [1..4]
[[1,1,1],[2,2,2],[3,3,3],[4,4,4]]
Prelude> fmap (replicate 3) [1..4]
[[1,1,1],[2,2,2],[3,3,3],[4,4,4]]
Prelude> concat [[1,2],[3,4]]
[1,2,3,4]
Prelude> concat (map (replicate 3) [1..4])
[1,1,1,2,2,2,3,3,3,4,4,4]
Prelude> concat $ map (replicate 3) [1..4]
[1,1,1,2,2,2,3,3,3,4,4,4]
Prelude> concatMap (replicate 3) [1..4]
[1,1,1,2,2,2,3,3,3,4,4,4]
Prelude> replicate 3 `concatMap` [1..4]
[1,1,1,2,2,2,3,3,3,4,4,4]
Prelude> [1..4] >>= replicate 3
[1,1,1,2,2,2,3,3,3,4,4,4]
應該很清楚flatMap
是先映射然后是flat,你平坦化地圖的輸出,而不是展平你要處理的輸入列表(這不是flatMap
,這沒有名字,它只是一個扁平的然后映射)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.