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

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

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

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

4

1 に答える 1

95

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

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

-- Typeclassopedia、20ページ

fmapliftMHaskell ではモナドは自動的に関手ではなかったので存在します:

fmap と liftM の両方があるという事実は、Monad 型クラスが Functor インスタンスを必要としないという事実の不幸な結果です。数学的に言えば、すべてのモナドはファンクターですが。ただし、fmap と liftM は本質的に互換性があります。これは、任意の型が Functor のインスタンスでなくても Monad のインスタンスになることは (技術的な意味ではなく社会的な意味で) バグであるためです。

-- Typeclassopedia、33ページ

編集: agustuss の履歴mapfmap:

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

-- fmap がある場合、Haskell の map のポイントは何ですか?

于 2011-09-18T18:40:39.510 に答える