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

map :: (a -> b) -> [a] -> [b] fmap :: Functor f => (a -> b) -> fa -> fb liftM :: Monad m => (a -> b) -> ma -> mb 

为什么我们有三个不同的function基本上是一样的?

map存在,可以简化列表和历史原因的操作(参见Haskell中有什么关于fmap的地图? )。

3你可能会问为什么我们需要一个单独的地图function。 为什么不直接抛弃当前仅用于列表的map函数,而是将fmap重命名为map呢? 那么,这是一个很好的问题。 通常的观点是,有人刚刚学习Haskell,当使用错误的地图时,宁可看到有关列表的错误,而不是关于Functors。

– Typeclassopedia ,第20页

fmapliftM存在是因为monad在Haskell中不是自动的函子:

事实上,我们同时具有fmap和liftM是Monadtypes类不需要Functor实例的一个不幸后果,即使在math上说,每个monad都是一个函子。 然而,fmap和liftM本质上是可以互换的,因为它是一个错误(在社会上而不是技术意义上),任何types都是Monad的实例,而不是Functor的实例。

– Typeclassopedia ,第33页

编辑:agustuss的mapfmap的历史:

实际上并不是这种情况。 发生了什么事情是,地图的types被推广到Haskell 1.3中的Functor。 也就是说,在Haskell 1.3 fmap被称为map。 然后在Haskell 1.4中恢复了这个变化,引入了fmap。 这种变化的原因是教学法; 在向初学者教授Haskell时,一般的地图types使错误信息更难以理解。 我认为这不是解决问题的正确方法。

– 当有fmap时,Haskell中的地图点是什么?

    Interesting Posts