それらの効用関数を定義することによって
implicit def eitherOps[E, A](v: Either[E, A]) = new {
def map[B](f: A => B) = v match {
case Left(e) => Left(e)
case Right(a) => Right(f(a))
}
def flatMap[B](f: A => Either[E, B]) = v match {
case Left(e) => Left(e)
case Right(a) => f(a)
}
def or(a: A) = v match {
case Left(_) => Right(a)
case x => x
}
}
def secure[A, B](f: A => B) = new {
def run(a: A): Either[Trowable, B] = try {
Right(f(a))
} catch {
case e => Left(e)
}
}
とあなたの単純化
def fA(s : String) = 7
def fB(i : Int) = 1.0
def fC(d : Double) = true
我々が持っています:
def test(s: String): Either[Throwable, Double] = for {
a <- secure(fA).run(s).or(0)
b <- secure(fB).run(a).or(0.0)
c <- secure(fC).run(b).or(false)
} yield result(a, b, c)
編集
これは実行可能ファイルですが、悲しいことに、より冗長なコードスニペットです
object Example {
trait EitherOps[E, A] {
def self: Either[E, A]
def map[B](f: A => B) = self match {
case Left(e) => Left(e)
case Right(a) => Right(f(a))
}
def flatMap[B](f: A => Either[E, B]) = self match {
case Left(e) => Left(e)
case Right(a) => f(a)
}
def or(a: A) = self match {
case Left(_) => Right(a)
case x => x
}
}
trait SecuredFunction[A, B] {
def self: A => B
def secured(a: A): Either[Throwable, B] = try {
Right(self(a))
} catch {
case e => Left(e)
}
}
implicit def eitherOps[E, A](v: Either[E, A]) = new EitherOps[E, A] {
def self = v
}
implicit def opsToEither[E, A](v: EitherOps[E, A]) = v.self
implicit def secure[A, B](f: A => B) = new SecuredFunction[A, B]{
def self = f
}
def fA(s : String) = 7
def fB(i : Int) = 1.0
def fC(d : Double) = true
def result(i : Int, d : Double, b : Boolean) = {
if (b) d else i
}
def test(s: String): Either[Throwable, Double] = for {
a <- (fA _).secured(s) or 0
b <- (fB _).secured(a) or 0.0
c <- (fC _).secured(b) or false
} yield result(a, b, c)
}