鉴于这种简单的计算,我无法清楚地看到使用适用于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
两个计算都以无结束,因此最终结果是相同的。我可以看到的唯一区别是,在使用应用语法时,在for comprehension中没有temporaray访问这些变量。
此外,只有一个None值会停止整个计算。我认为应用意味着&#34;不依赖于计算结果&#34;
答案 0 :(得分:5)
applicative builder语法将评估每个术语,不能使用先前计算的结果。但是,即使第一个结果为None,仍将评估所有其他表达式。
然而,在理解的情况下,它会快速失败&#39; (在你的情况下,它不会评估无后的任何其他表达式),而且你可以访问先前计算的结果。
不要将这些事情视为不同的 样式 ,它们会调用具有不同行为的不同函数:即flatMap vs apply
答案 1 :(得分:1)
Monads代表顺序计算,其中每个下一次计算取决于之前的计算(如果先前的计算是空的,则无法继续,因此“快速失败”),更一般的monadic计算示例:< / p>
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
的价值。