W jaki sposób mogę (najlepiej) przekonwertować opcję zwróconą przez wywołanie metody na próbę (według preferencji, chociaż może to być poprawne albo scalanie \/
lub nawet sprawdzanie poprawności), w tym określanie wartości błędu, jeśli jest to właściwe?Jak mogę (najlepiej) przekonwertować opcję na próbę?
Na przykład, Mam następujący kod, który czuje kludgy, ale ma przynajmniej zrobić (większość) zadanie:
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"))
}
}
}
Czuje się jak nie powinno być sposobem na mecz finałowy być przekształcił się w mapę lub płaską mapę lub podobną konstrukcję i włączony do poprzedniej dla zrozumienia.
Ponadto, wolałbym móc określić inny komunikat o błędzie, jeśli nie powiodło się wywołanie zwracania Opcji [A] z ARef (zwrócono Brak) w porównaniu do niepowodzenia sprawdzania BRef (zależy mi tylko na poznaniu jednego powodu na awarię, więc walidacja nie wydaje się idealnym rozwiązaniem).
Czy to odpowiednie miejsce do korzystania z transformatora Monada? Jeśli tak, to czy skalak dostarcza odpowiedni, czy może ktoś da przykład tego, jak by wyglądał?
Czy masz na myśli coś takiego jak 'try {abRef.getOrElse (throw new MismatchException ("No B okaże się pasować do B-ref")) lub' '} {abRef.map Success (_)} .getOrElse (awaria (nowy wyjątek MismatchException ("Nie znaleziono B pasującego do B-ref A")))? – senia
@senia więcej tego ostatniego: 'abRef.map {Success (_)} .getOrElse (Niepowodzenie (nowy wyjątek MismatchException (" Nie znaleziono B pasującego do A-B "))), ale wydaje się, że powinno być możliwe - i bardziej idiomatyczne - w jakiś sposób zbudować to w zrozumieniu. – Shadowlands
Na marginesie, dlaczego nie użyć 'filter' na' Option' - tj. Zastąpić 'for' -rozumienie za pomocą' get [A] (aRef) .map (_. BRef) .filter (validBRefs.contains) ' ? –