你可以使用.flatMap(identity)
的方法validateCombination
生產ValidationNel[String, (Value, Value)]
和pattern matching
的方法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
}
}
flatMap(身份)
通常你會使用嵌套容器的方法flatten
得到M[T]
從M[M[T]]
。它適用於Future
,Option
,Try
,收藏等。
在這種情況下type M[T] = ValidationNel[String, T]
。
我不知道爲什麼沒有方法flatten
在Validation
,但你總是可以使用flatMap(identity)
代替flatten
。
匹配
作爲Ben Jamesnoted,flatMap
上Validation
是可疑。你總是可以使用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) => ??? }
。
如果您發現自己在Tuple
上使用獲得者_N
,那麼您可能應該使用模式匹配。
的理解
至於Daniel C. Sobralnoted的理解可能更容易理解。
你可以用它在你的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
關鍵字。
注意,對於修真呼籲validateCombination(p1, p2)
flatMap
,所以你會從validate1(p3)
的情況下,失去了錯誤信息validateCombination(p1, p2)
是Failure
。相反,|@|
收集來自雙方的所有錯誤消息。
雖然我會用理解 - 這更容易理解,恕我直言。 –
「驗證」並不平坦,因爲它不打算有單子。實際上,'flatMap'方法是可疑的。但是有一些方法可以在驗證的等價物上運行操作,並再次轉換回來,例如'v.disjunctioned(_。flatten)' –
@ DanielC.Sobral:你的意思是「理解而不是'| @ |'」?我認爲重點是保持'| @ |'不變。感謝您的建議。你介意我將它添加到我的答案? – senia