繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM