Discord is now Scala’s main chat platform. Please join us at https://discord.com/invite/scala
trait Expr { def eval: Either[String, Double] }
sealed trait BinOp extends Expr {
def a: Expr
def b: Expr
def op: (Double, Double) => Either[String, Double]
protected def safe(f: (Double, Double) => Double): (Double, Double) => Either[String, Double] =
(xa, xb) => Right(f(xa, xb))
def eval = a match {
case Left(s) => Left(s)
case Right(xa) => b match {
case Left(s) => Left(s)
case Right(xb) => op(xa, xb)
}
}
final case class Add(a: Expr, b: Expr) extends BinOp { val op = safe(_ + _) }
final case class Sub(a: Expr, b: Expr) extends BinOp { val op = safe(_ - _) }
final case class Mul(a: Expr, b: Expr) extends BinOp { val op = safe(_ * _) }
final case class Div(a: Expr, b: Expr) extends BinOp {
val op = (xa, xb) => if (xb == 0) Left("Division by 0") else Right(xa / xb)
}
Left
and Right
prettyPrint
, overriding breaks everywhere