mel*_*ton 10 functional-programming scala flatmap
我一直在研究FP语言(关闭和开启)一段时间,并且使用过Scala,Haskell,F#和其他一些语言.我喜欢我所看到的并理解FP的一些基本概念(绝对没有类别理论的背景 - 所以请不要谈数学,请).
所以,给定一个类型,M[A]我们有map一个函数,A=>B并返回一个M[B].但我们也有flatMap一个功能A=>M[B]并返回一个M[B].我们也有flatten一个M[M[A]]并且返回一个M[A].
此外,许多的来源我已阅读形容flatMap为map其次flatten.
所以,鉴于这flatMap似乎相当于flatten compose map,它的目的是什么?请不要说它是支持'for comprehensions',因为这个问题确实不是Scala特有的.我不太关心语法糖,而不是我背后的概念.Haskell的bind运算符(>>=)也出现了同样的问题.我相信它们都与某些类别理论概念有关,但我不会说那种语言.
我已经看过Brian Beckman的精彩视频Do not Fear the Monad不止一次,我想我看到那flatMap是monadic组合运算符,但我从未真正看到它使用了他描述这个运算符的方式.它执行此功能吗?如果是这样,我该如何将该概念映射到flatMap?
顺便说一句,我在这个问题上写了很长的文章,上面有很多列表显示我试图深入了解其中的实验flatMap,然后遇到了这个回答我的一些问题的问题.有时我讨厌Scala暗示.他们真的可以在水中浑浊.:)
Ele*_*fee 26
FlatMap,在其他一些语言中被称为"绑定",就像你自己为功能组合所说的那样.
想象一下,你有一些像这样的功能:
def foo(x: Int): Option[Int] = Some(x + 2)
def bar(x: Int): Option[Int] = Some(x * 3)
Run Code Online (Sandbox Code Playgroud)
这些函数运行良好,调用foo(3)返回Some(5),并调用bar(3)返回Some(9),我们都很高兴.
但是现在你遇到了需要你不止一次做这个操作的情况.
foo(3).map(x => foo(x)) // or just foo(3).map(foo) for short
Run Code Online (Sandbox Code Playgroud)
干完了,对吗?
除了不是真的.上面的xpression的输出是Some(Some(7)),而不是Some(7),如果你现在想要在最后链接另一个地图,你不能,因为foo并bar采取Int,而不是Option[Int].
输入 flatMap
foo(3).flatMap(foo)
Run Code Online (Sandbox Code Playgroud)
将返回Some(7),和
foo(3).flatMap(foo).flatMap(bar)
Run Code Online (Sandbox Code Playgroud)
退货Some(15).
这很棒!使用flatMap允许您链形状的函数A => M[B],以遗忘(在前面的示例中A和B是Int,和M是Option).
从技术上讲,更多; flatMap和bind具有该签名M[A] => (A => M[B]) => M[B],这意味着它们采取一个"包装"的值,例如Some(3),Right('foo)或List(1,2,3)通过通常会采取展开的值,如上述的功能推它foo和bar.它通过首先"展开"值,然后将其传递给函数来完成此操作.
我已经看到了用于此的盒子类比,所以请观察我熟练绘制的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
Run Code Online (Sandbox Code Playgroud)
要解决这个问题,如果你的函数没有返回monad,你只需要使用常规map函数
foo(3).flatMap(foo).flatMap(bar).map(baz)
Run Code Online (Sandbox Code Playgroud)
哪个会回来 Some("15 is a number")
| 归档时间: |
|
| 查看次数: |
1229 次 |
| 最近记录: |