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
有什么好处?您何时会使用|@|
代替<*>
?
答案 0 :(得分:3)
更好的类型推断
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)
答案 1 :(得分:0)
一方面没有其他优点,但正如你所看到的那样,Applicative Builder并不需要,你的功能是在F的背景下进行的。在我看来,它的括号使用方式更加平易近人。
您还可以说Applicative Builder构建临时对象,因此在使用性能非常关键的代码和/或循环时,您应该避免使用它。在这种情况下,您可以使用其他替代方法,例如:Applicative[Option].apply2(3.some, 4.some)(f)
。这又与|@|
语法非常接近,只是您不必计算要为f(n1, n2, ...)
提供的参数数量。