您可以使用.flatMap(identity)
in 方法validateCombination
来生成ValidationNel[String, (Value, Value)]
和pattern matching
in 方法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所 指出的,flatMap
onValidation
是可疑的。你总是可以使用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 调用flatMap
on validateCombination(p1, p2)
,因此您将丢失来自validate1(p3)
in case validateCombination(p1, p2)
is 的错误消息Failure
。相反,|@|
从双方收集所有错误消息。