2016-10-13 5 views
8

今度は、Haskellの講義でMonadsとの関係で "フラットマップ"と言われたとき、それは理由のため「フラット」と呼ばれていました。 。だから、fmapとHaskellの "flat map"

[[1,2],[3,4]] 

は、それが

[1,2,3,4] 

であるかのように処理されるだろう。しかし、今、私はFMAPとマップは基本的に同じものであることを発見し、ファンクタのための1つのアプリケーションと他の唯一の違いちょうどリストのために。そして、それは結局、マップを使用するときにエラーメッセージを混乱させないようにするためだけに行われました。

本当ですか?もしそうならば、なぜfmapのfは "フラット"を意味するのですか?なぜ、 "ファンクタマップ"ではないのですか?

+3

'fmap'の' f'は 'flat'を意味するものではありません。 Haskellの 'flatMap'に相当するのは'(>> =) 'です。リストの 'map'関数が最初に定義されたので、より一般的な' fmap'関数のために別の名前が必要でした。 – Lee

+3

'fmap'は、リストファンクタ以外の他のファンクタへの' map'の一般化です。 'fmap'が' flat map'の略であるとあなたが言った人は間違っていました。 – chepner

+4

"フラットマップ"と言ったときに、あなたが指摘している講義は 'fmap'を参照していたと確信していますか? 'concatMap'(別名' >> = ')を参照していたのであれば、他の言語では' flatMap'とよく呼ばれ、期待通りに動作していれば意味があります。 – sepp2k

答えて

19

ffmapはなぜ「ファンクターマップ」ではないのですか?

あなたの直感は正しいです:ffmapでないすべての「ファンクタマップ」ではなく、「フラットマップ」についてスタンド。実際、PureScriptのような新しい言語では、名前はちょうどmapです。 Haskell mapがリストの最初に定義されたので、新しい名前が登場するのは困難でした。 FunctorからFを使用するのは、特に創造的ではないが、簡単な選択でした。

講師は、モナド結合機能、>>=を参照していた可能性が高いです。 x >>= fjoin (fmap f x)と等価であるため、他の言語では、結合もflatMapと呼ばれることがあります。それはたとえば、あなたがリストに期待する行動を持っています

> [1,2,3] >>= \x -> [x,x] 
[1,1,2,2,3,3] 

それがこの「フラットマップは、」再帰的に任意の深さに平らにしないこと、しかし、心に留めておくことが重要です。実際に、このような関数を書くことは、複雑なtypeclassトリッキーがなければ、Haskellでは本当に可能ではありません。自分で試してみてください:flatten関数の型シグネチャは、リストに直接作用するものでも何のように見えますか?それはfmapのようなものですが、すべての出力要素はファンクタに包まれ、そして>>=が浅く、単一のラッパーに結果を「平坦化」する必要があります。

flatten :: ??? -> [a] 

>>=機能は、比較して非常に簡単です。この操作はモナドの本質であり、>>=関数はMonadの型クラスに存在しますが、fmapFunctorです。

この回答は元の質問のコメントの一部から取られているので、私はそれをコミュニティのwikiと記しました。編集と改善は大歓迎です。

+0

これは単なる数字ではなく、異なる深さのリストでさえ、[[[1,2]]、[3]、[4]] >> = \ x - > x'は ':: [[1,2]、3,4]ではなく、[t]、Num t)=> [[t]] 'である。 – trans

+0

@trans [[[1,2]]、[3]、[4]] 'は有効なHaskell値ではありません。それは型がありません。深さに一貫性がないので、Num t => [[t]] 'またはNum t => [[[t]]]でもありません。 –

+0

あなたがそのタイプを得る理由は、 'Num'の動作のためです。したがって、' [1、2] 'が' Num'を持つことを期待する 'Num t => [[t]]'のタイプを推論します。インスタンス。もちろん、そうではありません。より明確な結果を得るために数字以外の数字で試してみてください。 –

0

ハスケルでflatMapを実行する方法の明示的な同等の例を次に示します。 (これがない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は、マップが最初にして平らであることは明らかであるべきで、これは何を持っていません名前、それは単なる平らで、次に地図です)。

関連する問題