Я думаю, что вы могли бы выиграть от использования Box Lift , который имеет Full
(то есть Some
), Empty
(то есть None
) и Failure
(Empty
спричина, почему это пусто, и это может быть приковано цепью).У Дэвида Поллака есть хорошее сообщение в блоге , представляющее его.Короче говоря, вы можете сделать что-то вроде этого (не проверено):
def validate1: Box[String]
def validate2: Box[String]
def validate3: Box[String]
val validation = for (
validation1 <- validate1 ?~ "error message 1"
validation2 <- validate2 ?~ "error message 2"
validation3 <- validate3 ?~ "error message 3"
) yield "overall success message"
Это не короче, чем оригинальный пример, но, на мой взгляд, немного более логично с результатомуспешная проверка в Full
и неудачная проверка в Failure
.
Однако мы можем получить меньше.Во-первых, поскольку наша функция проверки возвращает Box[String]
, они могут возвращать Failure
s сами, и нам не нужно преобразовывать Empty
в Failure
самих:
val validation = for (
validation1 <- validate1
validation2 <- validate2
validation3 <- validate3
) yield "overall success message"
Но, Box
также есть метод or
, который возвращает тот же Box
, если это Full
, или другой Box
, если это не так.Это даст нам:
val validation = validate1 или validate2 или validate3
Однако эта строка останавливается при первой проверке success , а не при первой ошибке.Возможно, имеет смысл создать другой метод, который делает то, что вы хотите (возможно, под названием unless
?), Хотя я не могу сказать, что он действительно был бы гораздо более полезным, чем подход для понимания.
Однако вотнебольшая библиотека, которая делает это:
scala> class Unless[T](a: Box[T]) {
| def unless(b: Box[T]) = {
| if (a.isEmpty) { a }
| else b
| }
| }
defined class Unless
scala> implicit def b2U[T](b: Box[T]): Unless[T] = new Unless(b)
b2U: [T](b: net.liftweb.common.Box[T])Unless[T]
scala> val a = Full("yes")
a: net.liftweb.common.Full[java.lang.String] = Full(yes)
scala> val b = Failure("no")
b: net.liftweb.common.Failure = Failure(no,Empty,Empty)
scala> val c = Full("yes2")
c: net.liftweb.common.Full[java.lang.String] = Full(yes2)
scala> a unless b
res1: net.liftweb.common.Box[java.lang.String] = Failure(no,Empty,Empty)
scala> a unless b unless c
res2: net.liftweb.common.Box[java.lang.String] = Failure(no,Empty,Empty)
scala> a unless c unless b
res3: net.liftweb.common.Box[java.lang.String] = Failure(no,Empty,Empty)
scala> a unless c
res4: net.liftweb.common.Box[java.lang.String] = Full(yes2)
Это быстрый взлом, основанный на моем ограниченном понимании системы типов Scala, как вы можете видеть в следующей ошибке:
scala> b unless a
<console>:13: error: type mismatch;
found : net.liftweb.common.Full[java.lang.String]
required: net.liftweb.common.Box[T]
b unless a
^
Тем не менее, этого должно быть достаточно, чтобы вы встали на правильный путь.
Конечно, Подъемник ScalaDocs содержит больше информации о Box .