繁体   English   中英

Haskell中的fmap和“flat map”

[英]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类型类中,但fmapFunctor

这个答案来自原始问题的一些评论,因此我将其标记为社区维基。 欢迎编辑和改进。

以下是一些如何在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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM