2012-06-23 2 views
9

Я довольно новичок в сказазе, и я начал с проверки.Сглаживание вложенных Scalaz валидаций

У меня есть некоторые функции проверки вида:

def validateXyz(...): ValidationNEL[String, String] = ... 

Я затем использовать аппликативный стиль для объединения нескольких валидаций, а затем вызвать другую функцию, которая также возвращает подтверждение:

(validateXyz(...) |@| validateAbc(...)) { (first, second) => 
    otherFunction(first, second) 
} 

где,

def otherFunction(first: String, second: String): ValidationNEL[String, String] = ... 

Однако при вызове вышеуказанного результирующего типа является:

val result: ValidationNEL[String, ValidationNEL[String, String]] = ... 

Я могу распаковать это, вызывая складка на результат с двумя функциями, то первый, который только распространяет NEL как неудачу, а второй, который только распространяет свой аргумент:

def propagateF(result: NonEmptyList[String]): ValidationNEL[String, String] = result.fail 
def propagateV(result: ValidationNEL[String, String]) = result 

result.fold(propagateF, propagateV) 
// result type: ValidationNEL[String, String] 

Этот работает и возвращает правильные типы и результаты. Однако это не похоже на правильное решение, поэтому я должен что-то пропускать. Что мне нужно сделать, чтобы избежать этой ужасной складки в конце?

ответ

8

То, что вы ищете, является монадическим join.

Дело в том, что сама по себе не является монадой, так как сторона ошибки несет структуру Semigroup, которая не может быть сохранена Monad. Но вы всегда можете опуститься в монаду Either, если вам нужно. Эта функциональность предоставляется flatMap.

(validateXyz(...) |@| validateAbc(...))(otherFunction).flatMap(x => x) 

Если у вас есть внешняя ошибка, результатом будет ошибка. Если у вас есть ошибка в успехе, результатом будет внутренняя ошибка. В противном случае результат будет успешным. Обратите внимание на невозможность иметь ошибку как внутри, так и снаружи. Вот почему вы должны использовать Applicative, а не Monad, если хотите совместить ошибки.

Смежные вопросы