web-dev-qa-db-ja.com

map、fmap、liftMがあるのはなぜですか?

map :: (a -> b) -> [a] -> [b]

fmap :: Functor f => (a -> b) -> f a -> f b

liftM :: Monad m => (a -> b) -> m a -> m b

本質的に同じことをする3つの異なる関数があるのはなぜですか?

99
fredoverflow

mapは、リストの操作を簡素化するために存在し、歴史的な理由から( fmapがある場合のHaskellのmapのポイントは何ですか? ) 。

別のマップ関数が必要な理由を尋ねるかもしれません。現在のリストのみのマップ関数を廃止し、代わりにfmapの名前をmapに変更しないのはなぜですか?まあ、それは良い質問です。通常の議論は、Haskellを学んだばかりの人は、mapを誤って使用すると、Functorについてではなく、リストについてのエラーを見たほうがよいということです。

- Typeclassopedia 、20ページ

fmapliftMが存在するのは、モナドがHaskellで自動的に機能しないためです。

FmapとliftMの両方があるという事実は、数学的にはすべてのモナドがファンクターであるにもかかわらず、Monad型クラスがFunctorインスタンスを必要としないという事実の不幸な結果です。ただし、fmapとliftMは基本的に交換可能です。これは、Functorのインスタンスではなく、Monadのインスタンスになるすべての型のバグ(技術的な意味ではなく社会的な意味)であるためです。

- Typeclassopedia 、33ページ

編集:agustussのmapおよびfmapの履歴:

それは実際にそれが起こる方法ではありません。起こったのは、マップのタイプがHaskell 1.3のFunctorをカバーするように一般化されたことです。つまり、Haskell 1.3ではfmapはmapと呼ばれていました。この変更はHaskell 1.4で元に戻され、fmapが導入されました。この変更の理由は教育的でした。初心者にHaskellを教えるとき、非常に一般的なタイプのマップはエラーメッセージを理解することをより困難にしました。私の意見では、これは問題を解決する正しい方法ではありませんでした。

- fmapがある場合のHaskellのマップのポイントは何ですか?

90
li.davidm