Я не знаю Лифта, поэтому не могу ответить ни на какие вопросы о Лифте. Однако я нашел способ решить одну из ваших проблем - написать последовательность действий «проверяй и работай», не прибегая к сопоставлению вложенных шаблонов.
Основным используемым типом данных здесь является Option, но я уверен, что его будет легко адаптировать к вашим потребностям. Здесь мы хотим выполнить последовательность
- проверить состояние
- продолжить в случае успеха
- завершить и вернуть что-то иначе
Код выполняет своего рода короткое замыкание, когда встречает None, поэтому возвращаемое значение сохраняется при возврате последовательности действий. Для использования начинается с Option, затем пишется «ifSome», если Option является Some, и «ifNone», если Option является None, продолжайте, пока последовательность не будет завершена. Если None встречается в любой точке последовательности, Option, возвращенный параметром call-by-name для isNone, сохраняется и возвращается при вызове окончательного toOption. Используйте «toOption», чтобы получить фактический результат Option.
Посмотрите пример в "main" для некоторых вариантов использования. Удачи!
object Options {
class RichOption[A](a: Option[A]) {
def ifSome[B](f: A => Option[B]): RichOption[B] = a match {
case Some(x) => new RichOption(f(x))
case None => this.asInstanceOf[RichOption[B]]
}
def ifNone[B](f: => Option[B]): RichOption[B] = a match {
case Some(_) => this.asInstanceOf[RichOption[B]]
case None => new RichNone(f)
}
def toOption[A] = a
}
class RichNone[A](a: Option[A]) extends RichOption[A](a) {
override def ifSome[B](f: A => Option[B]): RichOption[B] = this.asInstanceOf[RichOption[B]]
override def ifNone[B](f: => Option[B]): RichOption[B] = this.asInstanceOf[RichOption[B]]
}
implicit def option2RichOption[A](a: Option[A]): RichOption[A] = new RichOption(a)
def main(args: Array[String]) {
println(Some("hello") ifSome(s => Some(s.toUpperCase)) toOption) // prints Some(HELLO)
println(Some("hello") ifNone(Some("empty")) toOption) // prints Some(hello)
println(Some("hello") ifSome(s => Some(s.toUpperCase)) ifNone(Some("empty")) toOption) // prints Some(HELLO)
println(Some("hello") ifNone(Some("empty")) ifSome(s => Some(s.toUpperCase)) toOption) // prints Some(HELLO)
println((None: Option[String]) ifSome(s => Some(s.toUpperCase)) toOption) // prints None
println((None: Option[String]) ifNone(Some("empty")) toOption) // prints Some(empty)
println((None: Option[String]) ifSome(s => Some(s.toUpperCase)) ifNone(Some("empty")) toOption) // prints Some(empty)
println((None: Option[String]) ifNone(Some("empty")) ifSome(s => Some(s.toUpperCase)) toOption) // prints Some(empty)
println(Some("hello world") ifSome(s => Some(s.toUpperCase)) ifNone(Some("empty")) ifSome(s => Some(s.length)) ifNone(None) toOption) // prints Some(11)
println(Some("hello world") ifSome(_ => None) ifNone(Some("goodbye world")) ifSome(s => Some(s.length)) ifNone(None) toOption) // prints Some(goodbye world)
println((None: Option[String]) ifSome(s => Some(s.toUpperCase)) ifNone(Some("empty")) ifSome(s => Some(s.length)) ifNone(None) toOption) // prints Some(empty)
println((None: Option[String]) ifSome(_ => None) ifNone(Some("goodbye world")) ifSome(s => Some(s.length)) ifNone(None) toOption) // prints Some(goodbye world)
}
}