簡體   English   中英

Haskell中的fmap和“flat map”

[英]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類型類中,但fmapFunctor

這個答案來自原始問題的一些評論,因此我將其標記為社區維基。 歡迎編輯和改進。

以下是一些如何在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM