scala中的applicative和monadic计算之间的区别

时间:2015-10-14 13:16:45

标签: scala scalaz applicative

鉴于这种简单的计算,我无法清楚地看到使用适用于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;

2 个答案:

答案 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的价值。