[英]fmap and “flat map” in Haskell
所有这一次,当任何Haskell演讲中谈到“平面地图”时,通常与Monads有关,我认为它被称为“平面”,原因是它平坦了容器。 所以
[[1,2],[3,4]]
将被处理就像它一样
[1,2,3,4]
但是现在我发现fmap和map基本上是一回事,唯一的区别是一个用于仿函数而另一个用于just列表。 最后,这只是在使用map时避免混淆错误消息。
真的吗? 如果是这样,为什么fmap中的f
意味着“平坦”,为什么不是“functor map”?
如果是这样,为什么
fmap
f
意味着“平坦”,为什么不是“functor map”?
你的直觉是对的: fmap
中的f
代表“functor map”,而不是“flat map”。 事实上,在较新的类似语言中,例如PureScript,名称只是map
。 不过,Haskell map
首先是为列表定义的,所以提出一个新名称很困难。 使用Functor中的F是一个简单的(如果不是特别有创意的话)选择。
讲师更可能是指monadic绑定函数, >>=
。 由于x >>= f
等于join (fmap fx)
,bind在其他语言中有时也称为flatMap
。 它具有您在列表中所期望的行为,例如:
> [1,2,3] >>= \x -> [x,x]
[1,1,2,2,3,3]
但是,请记住,这个“平面地图”不会递归地变平到任意深度,这一点很重要。 实际上,如果没有复杂的类型类技巧,在Haskell中编写这样的函数实际上是不可能的。 自己尝试一下: flatten
函数的类型签名是什么样的,甚至是直接在列表上运行的?
flatten :: ??? -> [a]
相比, >>=
函数非常简单:它就像fmap
一样,但是每个输出元素都必须包含在fmap
函数中,并且>>=
浅浅地将结果“展平”成一个包装器。 这个操作是monad的本质,这就是为什么>>=
函数存在于Monad
类型类中,但fmap
在Functor
。
这个答案来自原始问题的一些评论,因此我将其标记为社区维基。 欢迎编辑和改进。
以下是一些如何在Haskell中执行flatMap
明确等效示例。
Prelude> map (replicate 3) [1..4]
[[1,1,1],[2,2,2],[3,3,3],[4,4,4]]
Prelude> fmap (replicate 3) [1..4]
[[1,1,1],[2,2,2],[3,3,3],[4,4,4]]
Prelude> concat [[1,2],[3,4]]
[1,2,3,4]
Prelude> concat (map (replicate 3) [1..4])
[1,1,1,2,2,2,3,3,3,4,4,4]
Prelude> concat $ map (replicate 3) [1..4]
[1,1,1,2,2,2,3,3,3,4,4,4]
Prelude> concatMap (replicate 3) [1..4]
[1,1,1,2,2,2,3,3,3,4,4,4]
Prelude> replicate 3 `concatMap` [1..4]
[1,1,1,2,2,2,3,3,3,4,4,4]
Prelude> [1..4] >>= replicate 3
[1,1,1,2,2,2,3,3,3,4,4,4]
应该很清楚flatMap
是先映射然后是flat,你平坦化地图的输出,而不是展平你要处理的输入列表(这不是flatMap
,这没有名字,它只是一个扁平的然后映射)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.