2015-03-08 4 views
2

Предположим, мне нужно проверить параметры запроса. Результатом проверки является либо Success, либо Failure с NonEmptyList[String]. Я, вероятно, могу использовать ValidationNel[String, Unit], но, похоже, немного переборщил. Думаю, мне нужна простая абстракция (см. Ниже).Как реализовать простую проверку в Scala

trait ValidationResult 
object Success extends ValidationResult 
class Failure(errors: NonEmptyList[String]) extends ValidationResult 

и бинарная операция andAlso объединить два результата:

trait ValidationResult { 
    def andAlso(other: ValidationResult): ValidationResult = 
    (this, other) match { 
     case (Success, Success) => Success 
     case (Success, failure @ Failure(_)) => failure 
     case (failure @ Failure(_), Success) => failure 
     case (Failure(errors1), Failure(errors2)) => Failure(errors1 + errors2) 
    } 
} 

Теперь, если я проверить три параметра с функциями checkA, checkB и checkC я могу легко сочинять их следующим образом:

def checkA(a: A): ValidationResult = ... 
def checkB(b: B): ValidationResult = ... 
def checkC(c: C): ValidationResult = ... 
def checkABC(a: A, b: B, c: C) = checkA(a) andAlso checkB(b) andAlso checkC(c) 

Имеет ли смысл?
Имеет ли эта абстракция имя? Может быть, Monoid?
Является ли он реализован в scalaz или любой другой библиотеке scala?

ответ

3

Это действительно Monoid, и вы можете быть более точным: это List[String] (вплоть до изоморфности). ValidationResult действительно изоморфен List[String], с Success для Nil и andAlso является конкатенацией :::/++.

Это имеет смысл, ValidationResult - это список ошибок, а когда их нет, это означает успех.

Однако, как вы заметили в начале, все это составляет ValidationNel[String, Unit], где Unit, «никаких данных, представляющих интерес», является интересной частью. Если вы будете обрабатывать фактические данные отдельно. Вы можете немного выиграть здесь, и это немного избегает синтаксиса Applicative, посыпая ваш код |@| и тому подобное; также, не часто упоминаемая цена Monads и Co, что упрощает работу с отладчиком. Но есть недостаток, так как ваш код растет с местами, где могут возникать ошибки, и управление потоком вручную быстро станет болезненным, и я бы не пошел таким путем.

Обычная альтернатива - исключения.

+0

Спасибо. Я попытаюсь продолжить работу с моноидом, потому что мне нужно это только для проверки вывода в моих тестах сейчас. – Michael

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