为什么我们有地图,fmap和liftM?

时间:2022-05-14 01:24:11
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?

为什么我们有三个不同的函数本质上是一样的?

1 个解决方案

#1


80  

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

map的存在是为了简化列表上的操作,并基于历史原因(在Haskell中,当有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.

你可能会问为什么我们需要一个单独的地图功能。为什么不直接取消当前的列表功能,将fmap重命名为map呢?这是个好问题。通常的观点是,当使用map错误时,只学习Haskell的人更愿意看到列表的错误而不是函数。

-- Typeclassopedia, page 20

——Typeclassopedia,第20页

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

fmap和liftM之所以存在,是因为在Haskell中,monads并不是自动运行的函数:

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.

事实上,我们有fmap和liftM,这是一个不幸的结果,因为Monad类型的类不需要一个函数实例,即使从数学上讲,每个Monad都是一个函数。但是,fmap和liftM本质上是可互换的,因为它是一个bug(在社会上而不是技术意义上),对于任何类型的Monad实例来说,它都不是一个函数的实例。

-- Typeclassopedia, page 33

——Typeclassopedia,第33页

Edit: agustuss's history of map and fmap:

编辑:agustuss的地图和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.

实际上并不是这样的。在Haskell 1.3中,映射的类型被一般化以覆盖函子。即。在Haskell 1.3 fmap中被称为map。在Haskell 1.4和fmap中恢复了这个更改。这一变化的原因是教育学;当向初学者讲授Haskell时,非常普遍的地图类型使得错误信息更难理解。在我看来,这不是解决问题的正确方法。

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

——在Haskell中,当有fmap的时候,地图的意义是什么?

#1


80  

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

map的存在是为了简化列表上的操作,并基于历史原因(在Haskell中,当有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.

你可能会问为什么我们需要一个单独的地图功能。为什么不直接取消当前的列表功能,将fmap重命名为map呢?这是个好问题。通常的观点是,当使用map错误时,只学习Haskell的人更愿意看到列表的错误而不是函数。

-- Typeclassopedia, page 20

——Typeclassopedia,第20页

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

fmap和liftM之所以存在,是因为在Haskell中,monads并不是自动运行的函数:

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.

事实上,我们有fmap和liftM,这是一个不幸的结果,因为Monad类型的类不需要一个函数实例,即使从数学上讲,每个Monad都是一个函数。但是,fmap和liftM本质上是可互换的,因为它是一个bug(在社会上而不是技术意义上),对于任何类型的Monad实例来说,它都不是一个函数的实例。

-- Typeclassopedia, page 33

——Typeclassopedia,第33页

Edit: agustuss's history of map and fmap:

编辑:agustuss的地图和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.

实际上并不是这样的。在Haskell 1.3中,映射的类型被一般化以覆盖函子。即。在Haskell 1.3 fmap中被称为map。在Haskell 1.4和fmap中恢复了这个更改。这一变化的原因是教育学;当向初学者讲授Haskell时,非常普遍的地图类型使得错误信息更难理解。在我看来,这不是解决问题的正确方法。

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

——在Haskell中,当有fmap的时候,地图的意义是什么?