ApplicativeBuilder有什么优势?

What are advantages of ApplicativeBuilder?

Applicative提供了"operator"<*>,我可以这样使用:

val f: (Int, Int) => Int = {(x, y) => x + y}
1.some <*> (2.some <*> f.curried.some)

除此之外 scalaz 提供 ApplicativeBuilder:

(1.some |@| 2.some)(f)

ApplicativeBuilder有什么优点?您什么时候会使用 |@| 而不是 <*>

两者并没有真正的优势,但正如您所见,Applicative Builder 不需要您的函数是柯里化的,并且在 F 的上下文中。在我看来,它也有更平易近人的用法的括号。

您也可以说 Applicative Builder 构建临时对象,因此在性能非常关键的代码 and/or 循环中使用时,您可能应该避免使用它。在这种情况下,您可以使用另一种选择,例如:Applicative[Option].apply2(3.some, 4.some)(f)。这再次非常接近 |@| 语法,只是您不必计算要为 f(n1, n2, ...).

提供的参数数量

更好的类型推断

scala> ^(1.right[String], 2.right[String])(_ + _)
<console>:16: error: type mismatch;
 found   : scalaz.\/[String,Int]
 required: ?F[?A]
Note that implicit conversions are not applicable because they are ambiguous:
 both method ToAssociativeOps in trait ToAssociativeOps of type [F[_, _], A, B](v: F[A,B])(implicit F0: scalaz.Associative[F])scalaz.syntax.AssociativeOps[F,A,B]
 and method ToBitraverseOps in trait ToBitraverseOps of type [F[_, _], A, B](v: F[A,B])(implicit F0: scalaz.Bitraverse[F])scalaz.syntax.BitraverseOps[F,A,B]
 are possible conversion functions from scalaz.\/[String,Int] to ?F[?A]
              ^(1.right[String], 2.right[String])(_ + _)
                                                 ^

scala> (1.right[String] |@| 2.right[String])(_ + _)
res1: scalaz.\/[String,Int] = \/-(3)