您可以使用.flatMap(identity)in 方法validateCombination来生成ValidationNel[String, (Value, Value)]和pattern matchingin 方法validate,如下所示:
def validateCombination(p1: String, p2: String): ValidationNel[String, (Value, Value)] = {
// I would like to write something like
(validate1(p1) |@| validate2(p2)) { (v1, v1) =>
(v1, v2).successNel[String]
}.flatMap(identity)
}
def validate(p1: String, p2: String, p3: String) = {
(validateCombination(p1, p2) |@| validate1(p3)) { case ((v1, v2), v3) =>
// Notice the three parameters I want to have here
}
}
平面地图(身份)
通常你会flatten在嵌套容器上使用方法来M[T]从M[M[T]]. 它适用于Future, Option, Try, 集合等。
在这种情况下type M[T] = ValidationNel[String, T]。
我不知道为什么没有方法flatten,Validation但你总是可以使用flatMap(identity)而不是flatten。
匹配
正如Ben James所 指出的,flatMaponValidation是可疑的。你总是可以使用match它来代替它:
(validate1(p1) |@| validate2(p2)) { (v1, v1) =>
(v1, v2).successNel[String]
} match {
case Success(s) => s
case Failure(f) => Failure(f)
}
模式匹配
模式匹配是处理元组的常用方法。例如,它因foldLeft方法而异,例如foldLeft(1 -> 2){ case ((a, b), c) => ??? }.
如果你发现自己在使用 getter _N,Tuple你可能应该使用模式匹配。
为了理解
正如Daniel C. Sobral 指出的理解可能更容易理解。
你可以validate像这样在你的方法中使用它:
def validate(p1: String, p2: String, p3: String) = {
for{
(v1, v2) <- validateCombination(p1, p2) // pattern matching
v3 <- validate1(p3)
} yield ??? // Your code here
}
它涉及没有case关键字的模式匹配。
请注意, for comprehension 调用flatMapon validateCombination(p1, p2),因此您将丢失来自validate1(p3)in case validateCombination(p1, p2)is 的错误消息Failure。相反,|@|从双方收集所有错误消息。