[英]Difference between applicative and monadic computation in scala
鉴于这种简单的计算,我无法清楚地看到使用适用于monadic风格的风格之间的区别。 那里有一些更好的例子(在scala中)什么时候使用一个而不是另一个。
println( (3.some |@| none[Int] |@| 4.some )( (a:Int,b:Int,c:Int) => { a + b + c } ) ) // prints None
println( for(
a <- Some(3);
b <- none[Int];
c <- Some(4)
) yield( a + b + c ) ) // prints None
两个计算都以None结尾,因此最终结果是相同的。 我可以看到的唯一区别是,在使用应用语法时,在for comprehension中没有temporaray访问这些变量。
此外,具有一个None值会停止整个计算。 我认为应用意味着“不依赖于之前的计算结果”
应用程序构建器语法将评估每个术语, 并且不能使用先前计算的结果。 但是,即使第一个结果为None,仍将评估所有其他表达式。
然而,对于for comprehension,它将“快速失败”(在你的情况下它不会在None之后评估任何进一步的表达式),而且你可以访问先前计算的结果。
不要将这些东西视为简单的不同风格 ,他们用不同的行为调用不同的函数:即flatMap vs apply
Monads表示顺序计算,其中每个下一个计算依赖于先前的计算(如果先前的计算为空,则无法继续,因此您“快速失败”),更一般的monadic计算示例:
println( for(
a <- Some(1);
b <- Some(a);
c <- Some(a + b)
) yield( a + b + c ) ) //=> 4
应用只是类固醇的fmap
,不仅是一个参数,而且映射函数本身可以是空的。 在您的情况下,它可以重写为:
4.some <*>
{ none[Int] <*>
{ 3.some <*>
{ (_: Int) + (_: Int) + (_: Int) }.curried.some } }
在某些步骤中,您的函数变为Option[Int => Int] = None
,但它不会停止将其应用于4.some
,只有结果为None
如预期的那样。 你仍然需要知道4.some
的价值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.