1. ホーム
  2. list

[解決済み] なぜmap, fmap, liftMがあるのですか?

2022-10-20 17:16:37

疑問点

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 はリストに対する操作を単純化するためと歴史的な理由で存在します ( Haskellにはfmapがあるのに、mapは何のためにあるのでしょうか? ).

なぜ別のマップ関数が必要なのかと聞かれるかもしれません。なぜ、現在の を廃止し、代わりにfmapをmapにリネームすればいいのでは?それは良い質問です。それは良い質問です。 Haskellを学び始めたばかりの人が、mapを間違って使った場合、リストに関するエラーよりも ファンクターに関するエラーよりもリストに関するエラーを見たいからです。

-- タイプ・クラス・ペディア 20ページ

fmap そして liftM が存在するのは、Haskellではモナドが自動的にファンクタにならなかったからです。

fmapとliftMの両方があるのは、モナド型クラスが モナド型クラスがファンクターインスタンスを必要としないという事実の不幸な結果です。 数学的に言えば、すべてのモナドはファンクタであるにもかかわらず、モナド型クラスがファンクタのインスタンスを必要としないという残念な結果です。 ファンクタである。しかし、fmapとliftMは本質的に交換可能である。 のインスタンスであることは(技術的というより社会的な意味での)バグである。 であることは(技術的というより社会的な意味で)バグです。

-- タイプ・クラス・ペディア 33ページ

編集:agustuss の歴史は mapfmap :

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

-- Haskellにはfmapがあるのに、mapは何のためにあるのでしょうか?