map :: (a -> b) -> [a] -> [b]
fmap :: Functor f => (a -> b) -> f a -> f b
liftM :: Monad m => (a -> b) -> m a -> m b
本質的に同じことを行う 3 つの異なる関数があるのはなぜですか?
map :: (a -> b) -> [a] -> [b]
fmap :: Functor f => (a -> b) -> f a -> f b
liftM :: Monad m => (a -> b) -> m a -> m b
本質的に同じことを行う 3 つの異なる関数があるのはなぜですか?
map
リストの操作を簡素化するために、また歴史的な理由から存在します ( fmap がある場合、Haskell でのマップのポイントは何ですか?を参照してください)。
別のマップ関数が必要な理由を尋ねるかもしれません。現在のリストのみの map 関数を廃止し、代わりに fmap の名前を map に変更しないのはなぜですか? いい質問ですね。通常の議論は、Haskell を学習したばかりの人が map を間違って使用すると、Functor よりもリストに関するエラーが表示されるというものです。
-- Typeclassopedia、20ページ
fmap
liftM
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 を初心者に教えるとき、非常に一般的なタイプのマップがエラー メッセージを理解しにくくしていました。私の意見では、これは問題を解決する正しい方法ではありませんでした。