当前位置:  开发笔记 > 编程语言 > 正文

为什么我们需要flatMap(一般情况下)?

如何解决《为什么我们需要flatMap(一般情况下)?》经验,为你挑选了1个好方法。

我一直在研究FP语言(关闭和开启)一段时间,并且使用过Scala,Haskell,F#和其他一些语言.我喜欢我所看到的并理解FP的一些基本概念(绝对没有类别理论的背景 - 所以请不要谈数学,请).

所以,给定一个类型,M[A]我们有map一个函数,A=>B并返回一个M[B].但我们也有flatMap一个功能A=>M[B]并返回一个M[B].我们也有flatten一个M[M[A]]并且返回一个M[A].

此外,许多的来源我已阅读形容flatMapmap其次flatten.

所以,鉴于这flatMap似乎相当于flatten compose map,它的目的是什么?请不要说它是支持'for comprehensions',因为这个问题确实不是Scala特有的.我不太关心语法糖,而不是我背后的概念.Haskell的bind运算符(>>=)也出现了同样的问题.我相信它们都与某些类别理论概念有关,但我不会说那种语言.

我已经看过Brian Beckman的精彩视频Do not Fear the Monad不止一次,我想我看到那flatMap是monadic组合运算符,但我从未真正看到它使用了他描述这个运算符的方式.它执行此功能吗?如果是这样,我该如何将该概念映射到flatMap

顺便说一句,我在这个问题上写了很长的文章,上面有很多列表显示我试图深入了解其中的实验flatMap,然后遇到了这个回答我的一些问题的问题.有时我讨厌Scala暗示.他们真的可以在水中浑浊.:)



1> Electric Cof..:

FlatMap,在其他一些语言中被称为"绑定",就像你自己为功能组合所说的那样.

想象一下,你有一些像这样的功能:

def foo(x: Int): Option[Int] = Some(x + 2)
def bar(x: Int): Option[Int] = Some(x * 3)

这些函数运行良好,调用foo(3)返回Some(5),并调用bar(3)返回Some(9),我们都很高兴.

但是现在你遇到了需要你不止一次做这个操作的情况.

foo(3).map(x => foo(x)) // or just foo(3).map(foo) for short

干完了,对吗?

除了不是真的.上面的xpression的输出是Some(Some(7)),而不是Some(7),如果你现在想要在最后链接另一个地图,你不能,因为foobar采取Int,而不是Option[Int].

输入 flatMap

foo(3).flatMap(foo)

将返回Some(7),和

foo(3).flatMap(foo).flatMap(bar)

退货Some(15).

这很棒!使用flatMap允许您链形状的函数A => M[B],以遗忘(在前面的示例中ABInt,和MOption).

从技术上讲,更多; flatMapbind具有该签名M[A] => (A => M[B]) => M[B],这意味着它们采取一个"包装"的值,例如Some(3),Right('foo)List(1,2,3)通过通常会采取展开的值,如上述的功能推它foobar.它通过首先"展开"值,然后将其传递给函数来完成此操作.

我已经看到了用于此的盒子类比,所以请观察我熟练绘制的MSPaint插图: 在此输入图像描述

这种展开和重新包装行为意味着如果我要引入第三个函数但不返回Option[Int]并尝试将flatMap 其添加到序列中,它将无法工作,因为flatMap期望您返回一个monad(在本例中为an Option)

def baz(x: Int): String = x + " is a number"

foo(3).flatMap(foo).flatMap(bar).flatMap(baz) // <<< ERROR

要解决这个问题,如果你的函数没有返回monad,你只需要使用常规map函数

foo(3).flatMap(foo).flatMap(bar).map(baz)

哪个会回来 Some("15 is a number")


这个答案清晰简洁,准确回答了问题的问题,并且有很棒的图形.我希望我可以两次投票
这可能是我见过的flatMap/bind背后概念的最佳描述.谢谢.
推荐阅读
有风吹过best
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有