为什么我们有map,fmap和liftM?

时间:2011-09-18 18:32:01

标签: list haskell monads redundancy functor

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

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

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

为什么我们有三种基本相同的功能?

1 个答案:

答案 0 :(得分:85)

map用于简化列表操作和历史原因(请参阅What's the point of map in Haskell, when there is fmap?)。

  

您可能会问我们为什么需要单独的地图功能。为什么不放弃当前   仅列表映射函数,并将fmap重命名为map?嗯,这是一个很好的问题。该   通常的说法是,有人刚刚学习Haskell,当使用地图不正确时,会很多   相反,看到有关列表的错误,而不是关于Functors。

- Typeclassopedia,第20页

fmapliftM存在是因为monads不是Haskell中的自动仿函数:

  

我们同时拥有fmap和liftM这一事实   Monad类型不需要的事实的不幸结果   一个Functor实例,尽管从数学上讲,每个monad都是一个   仿函数。但是,fmap和liftM基本上是可以互换的,因为它是   任何类型作为实例的错误(在社交而非技术意义上)   Monad也不是Functor的一个实例。

- Typeclassopedia,第33页

编辑:agustuss的mapfmap的历史记录:

  

实际上并不是这样的。发生的事情是,地图的类型被概括为涵盖Haskell 1.3中的Functor。即,在Haskell 1.3中,fmap被称为map。然后在Haskell 1.4中恢复此更改并引入了fmap。这种变化的原因是教学法;在向初学者教授Haskell时,非常一般的地图类型使得错误消息更难以理解。在我看来,这不是解决问题的正确方法。

- What's the point of map in Haskell, when there is fmap?