在观看了Nick Partidge关于派生scalaz的演示文稿之后,我开始查看这个示例,这真是太棒了:
import scalaz._
import Scalaz._
def even(x: Int) : Validation[NonEmptyList[String], Int]
= if (x % 2 ==0) x.success else "not even: %d".format(x).wrapNel.fail
println( even(3) <|*|> even(5) ) //prints: Failure(NonEmptyList(not even: 3, not even: 5))
我试图了解该<|*|>
方法在做什么,这是源代码:
def <|*|>[B](b: M[B])(implicit t: Functor[M], a: Apply[M]): M[(A, B)]
= <**>(b, (_: A, _: B))
好的,这相当令人困惑(!) - 但它引用了<**>
这样声明的方法:
def <**>[B, C](b: M[B], z: (A, B) => C)(implicit t: Functor[M], a: Apply[M]): M[C]
= a(t.fmap(value, z.curried), b)
所以我有几个问题:
- 为什么该方法似乎采用了一种类型参数 ( ) 的更高种类
M[B]
的类型,但可以传递 aValidation
(它有两个类型参数)? - 语法
(_: A, _: B)
定义了第二种(A, B) => Pair[A,B]
方法所期望的功能:在失败情况下 Tuple2/Pair 发生了什么?看不到元组!