这个例子来源于scala圣经级教程《Functional Programming in Scala》,由于本人跟着书中的代码敲了一遍,然后写了点测试代码验证了一下正确性,所以就放在这做个备忘吧。贴出来只是为了方便自己,如果看不懂,但是又感兴趣的就去看原书吧
。
package errorhandling
//hide std library `Either`, since we are writing our own
import scala.{Either => _}
sealed trait Either[+E, +A] {
def map[B](f: A => B): Either[E, B] = this match {
case Left(e) => Left(e)
case Right(a) => Right(f(a))
}
def flatMap[EE >: E, B](f: A => Either[EE, B]): Either[EE, B] =
this match {
case Left(e) => Left(e)
case Right(a) => f(a)
}
def orElse[EE >: E, AA >: A](b: => Either[EE, AA]): Either[EE, AA] =
this match {
case Left(_) => b
case Right(a) => Right(a)
}
def map2[EE >: E, B, C](b: Either[EE, B])(f: (A, B) => C): Either[EE, C] =
for {
a <- this
b1 <- b
} yield f(a, b1)
}
case class Left[+E](get: E) extends Either[E, Nothing]
case class Right[+A](get: A) extends Either[Nothing, A]
object Either {
def mean(xs: IndexedSeq[Double]): Either[String, Double] = if (xs.isEmpty) Left("empty list") else Right(xs.sum / xs.length)
def Try[A](a: => A): Either[Exception, A] = try Right(a) catch { case e: Exception => Left(e) }
def safeDiv(x: Int, y: Int): Either[Exception, Int] = try Right(x / y) catch {case e: Exception => Left(e) }
def traverse[E, A, B](es: List[A])(f: A => Either[E, B]): Either[E, List[B]] =
es match {
case Nil => Right(Nil)
case h :: t => (f(h) map2 traverse(t)(f)) (_ :: _)
}
def traverse_1[E, A, B](es: List[A])(f: A => Either[E, B]): Either[E, List[B]] =
es.foldRight[Either[E, List[B]]](Right(Nil))((a, b) => f(a).map2(b)(_ :: _))
def sequence[E, A](es: List[Either[E, A]]): Either[E, List[A]] =
traverse(es)(x => x)
def main(args: Array[String]): Unit = {
val f = (x: Int, y: Int) => x / y
val e = Either.Try(f(4, 0))
println(e)
val r = Either.Try(f(16, 8))
println(r)
val res = Try(f(16, 8)).map2(Try(f(22, 11)))((a: Int, b: Int) => a * b)
println(res)
val res1 = Try(f(16, 8)).map2(Try(f(22, 0)))((a: Int, b: Int) => a * b)
println(res1)
}
}
上述代码的运行结果是:
Left(java.lang.ArithmeticException: / by zero)
Right(2)
Right(4)
Left(java.lang.ArithmeticException: / by zero)