Как я могу (лучше всего) преобразовать Option, возвращаемый вызовом метода, в Try (по предпочтению, хотя может быть и «Libor», или «scalaz \/
», или даже «Validation»), включая указание значения «Отказ», если это уместно?
Например, у меня есть следующий код, который кажется неуклюжим, но, по крайней мере, выполняет (большую часть) работу:
import scala.util._
case class ARef(value: String)
case class BRef(value: String)
case class A(ref: ARef, bRef: BRef)
class MismatchException(msg: String) extends RuntimeException(msg)
trait MyTry {
// Given:
val validBRefs: List[BRef]
// Want to go from an Option[A] (obtained, eg., via a function call passing a provided ARef)
// to a Try[BRef], where the b-ref needs to be checked against the above list of BRefs or fail:
def getValidBRefForReferencedA(aRef: ARef): Try[BRef] = {
val abRef = for {
a <- get[A](aRef) // Some function that returns an Option[A]
abRef = a.bRef
_ <- validBRefs.find(_ == abRef)
} yield (abRef)
abRef match {
case Some(bRef) => Success(bRef)
case None => Failure(new MismatchException("No B found matching A's B-ref"))
}
}
}
Похоже, что должен быть способ преобразовать финальное совпадение в карту, плоскую карту или подобную конструкцию и включить в предыдущее для понимания.
Кроме того, я бы предпочел иметь возможность указать другое сообщение об ошибке, если вызов для возврата Option[A] из ARef завершился неудачно (возвращено None) по сравнению с ошибкой проверки BRef (мне важно знать только одну причину сбоя, поэтому scalaz Validation не кажется идеальным вариантом).
Это подходящее место для использования преобразователя монад? Если да, то предоставляет ли scalaz подходящий вариант или кто-нибудь может привести пример того, как он будет выглядеть?
Try{ abRef.getOrElse(throw new MismatchException("No B found matching A's B-ref")) }
илиabRef.map{ Success(_) }.getOrElse(Failure(new MismatchException("No B found matching A's B-ref")))
? - person senia   schedule 08.07.2013abRef.map{ Success(_) }.getOrElse(Failure(new MismatchException("No B found matching A's B-ref")))
, но кажется, что должно быть возможно - и более идиоматично - каким-то образом встроить это в понимание для. - person Shadowlands   schedule 08.07.2013filter
наOption
, то есть заменитьfor
-понимание наget[A](aRef).map(_.bRef).filter(validBRefs.contains)
? - person Travis Brown   schedule 08.07.2013