Вы можете использовать .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) => ??? }
.
Если вы обнаружили, что используете геттеры _N
на Tuple
, вам, вероятно, следует использовать соответствующий шаблон.
для понимания
Как 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
ключевого слова.
Обратите внимание, что для понимания вызовов flatMap
на validateCombination(p1, p2)
, так что вы будете потеряны сообщения об ошибках validate1(p3)
в случае validateCombination(p1, p2)
является Failure
. Наоборот, |@|
собирает все сообщения об ошибках с обеих сторон.
Хотя я бы использовал это для понимания - это легче понять, имхо. –
'Validation' не имеет сглаживания, потому что он не предназначен для монады. Фактически метод 'flatMap' сомнительный. Но есть методы для выполнения операций над эквивалентом '\ /' проверки и преобразования назад, например. 'v.disjunctioned (_. flatten)' –
@ DanielC.Sobral: вы имеете в виду «для понимания вместо' | @ | '"? Я думал, что нужно держать '| @ |' нетронутым. Спасибо за предложение. Не возражаете, я добавлю это к моему ответу? – senia