简体   繁体   English

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

[英]Why do we have map, fmap and liftM?

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? ). map存在以简化列表上的操作和历史原因( 当有fmap时,请参阅Haskell中的地图点是什么? )。

You might ask why we need a separate map function. 你可能会问为什么我们需要一个单独的map函数。 Why not just do away with the current list-only map function, and rename fmap to map instead? 为什么不放弃当前仅列表映射函数,并将fmap重命名为map? 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. 通常的论点是,有人在学习Haskell时,如果错误地使用地图,则更倾向于看到关于列表的错误,而不是关于Functors的错误。

-- Typeclassopedia , page 20 - Typeclassopedia ,第20页

fmap and liftM exist because monads were not automatically functors in Haskell: 存在fmapliftM ,因为monads不是Haskell中的自动fmap liftM

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. 我们同时拥有fmap和liftM的事实是Monad类型类不需要Functor实例这一事实的不幸结果,即使从数学上讲,每个monad都是一个算子。 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本质上是可以互换的,因为它是一个bug(在社交而不是技术意义上),任何类型的Monad实例都不是Functor的实例。

-- Typeclassopedia , page 33 - Typeclassopedia ,第33页

Edit: agustuss's history of map and fmap : 编辑:agustuss的mapfmap的历史:

That's not actually how it happens. 实际上并不是这样的。 What happened was that the type of map was generalized to cover Functor in Haskell 1.3. 发生的事情是,地图的类型被概括为涵盖Haskell 1.3中的Functor。 Ie, in Haskell 1.3 fmap was called map. 即,在Haskell 1.3中,fmap被称为map。 This change was then reverted in Haskell 1.4 and fmap was introduced. 然后在Haskell 1.4中恢复此更改并引入了fmap。 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. 在向初学者教授Haskell时,非常一般的地图类型使得错误消息更难以理解。 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? - 当有fmap时,Haskell中的地图有什么意义?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我们需要在使用 map 函数时将 list 写在前面,因为 split() 已经返回了一个列表? - Why do we need to write list at front while using map function as split() already returns a list? 我们为什么要这样使用? - Why do we use like this? Python:为什么列表没有find方法? - Python: Why Lists do not have a find method? 为什么数组没有添加和插入方法 - Why array do not have add and insert method 为什么我有无限循环? - Why do i have infinite while loop? 为什么我们需要图的 DFS 或 BFS 算法? - Why do we need DFS or BFS algorithms for graphs? 如果我们可以使用二维列表,为什么还要使用元组? - Why do we use tuples, if we can use a two dimensional list? 为什么我们要在 Flutter/Dart 中使用“List.Map()”函数之前使用“...”扩展运算符? - Why should we use "..." spread operator before using "List.Map()" function in Flutter/Dart? 如何在我们想要迭代 Oracle 中的 Map 列表的 mybatis 中进行批量插入 - How to do bulk insert in mybatis where we want to iterate over List of Map in Oracle 考虑到我们有一个带有节点和edges.am的图,我们如何表示边缘列表。 - how do we represent an edge list given that we have a graph with nodes and edges.am not talking about adjacency lists
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM