为什么我们有map,fmap和liftM? [英] Why do we have map, fmap and liftM?

查看:196
本文介绍了为什么我们有map,fmap和liftM?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

为什么我们有三种不同的函数可以做同样的事情?

解决方案

map 存在以简化列表和历史原因的操作(请参阅什么是Haskell中的地图点,何时有fmap?)。


<3>你可能会问为什么我们需要一个单独的地图功能。为什么不放弃目前的
list-only映射函数,并将fmap重命名为map?那么,这是一个很好的问题。
通常的观点是,有人刚刚学习Haskell,当使用map错误的时候,会有很多
而不是关于列表的错误,而不是关于Functors的错误。


- Typeclassopedia ,第20页



fmap liftM 存在,因为monads不是自动函子在Haskell中:


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


- Typeclassopedia ,第33页

编辑:agustuss历史 map fmap


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


-

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

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

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

Why do we have three different functions that do essentially the same thing?

map exists to simplify operations on lists and for historical reasons (see What's the point of map in Haskell, when there is fmap?).

3You might ask why we need a separate map function. Why not just do away with the current list-only map function, and rename fmap to map instead? Well, that’s a good question. The usual argument is that someone just learning Haskell, when using map incorrectly, would much rather see an error about lists than about Functors.

-- Typeclassopedia, page 20

fmap and liftM exist because monads were not automatically functors in Haskell:

The fact that we have both fmap and liftM is an unfortunate consequence of the fact that the Monad type class does not require a Functor instance, even though mathematically speaking, every monad is a functor. However, fmap and liftM are essentially interchangeable, since it is a bug (in a social rather than technical sense) for any type to be an instance of Monad without also being an instance of Functor.

-- Typeclassopedia, page 33

Edit: agustuss's history of map and fmap:

That's not actually how it happens. What happened was that the type of map was generalized to cover Functor in Haskell 1.3. I.e., in Haskell 1.3 fmap was called map. This change was then reverted in Haskell 1.4 and fmap was introduced. The reason for this change was pedagogical; when teaching Haskell to beginners the very general type of map made error messages more difficult to understand. In my opinion this wasn't the right way to solve the problem.

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

这篇关于为什么我们有map,fmap和liftM?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆