map :: (a -> b) -> [a] -> [b]
fmap :: Functor f => (a -> b) -> f a -> f b
liftM :: Monad m => (a -> b) -> m a -> m b
为什么我们有三种基本相同的功能?
答案 0 :(得分:85)
map
用于简化列表操作和历史原因(请参阅What's the point of map in Haskell, when there is fmap?)。
您可能会问我们为什么需要单独的地图功能。为什么不放弃当前 仅列表映射函数,并将fmap重命名为map?嗯,这是一个很好的问题。该 通常的说法是,有人刚刚学习Haskell,当使用地图不正确时,会很多 相反,看到有关列表的错误,而不是关于Functors。
- Typeclassopedia,第20页
fmap
和liftM
存在是因为monads不是Haskell中的自动仿函数:
我们同时拥有fmap和liftM这一事实 Monad类型不需要的事实的不幸结果 一个Functor实例,尽管从数学上讲,每个monad都是一个 仿函数。但是,fmap和liftM基本上是可以互换的,因为它是 任何类型作为实例的错误(在社交而非技术意义上) Monad也不是Functor的一个实例。
- Typeclassopedia,第33页
编辑:agustuss的map
和fmap
的历史记录:
实际上并不是这样的。发生的事情是,地图的类型被概括为涵盖Haskell 1.3中的Functor。即,在Haskell 1.3中,fmap被称为map。然后在Haskell 1.4中恢复此更改并引入了fmap。这种变化的原因是教学法;在向初学者教授Haskell时,非常一般的地图类型使得错误消息更难以理解。在我看来,这不是解决问题的正确方法。