Skip to content

Instantly share code, notes, and snippets.

@loxygenK
Created November 7, 2021 13:39
Show Gist options
  • Save loxygenK/955346739e160dc97153a1c48a02481a to your computer and use it in GitHub Desktop.
Save loxygenK/955346739e160dc97153a1c48a02481a to your computer and use it in GitHub Desktop.
case class EvaluationError(
val evaluating: Evaluate,
val reason: String,
val cause: String
)
trait Evaluate {
def evaluate: Either[EvaluationError, Double]
}
trait TwoHandEvaluation extends Evaluate {
def evaluateOperands(left: Evaluate, right: Evaluate): Either[EvaluationError, (Double, Double)] = {
for {
l <- left.evaluate.right
r <- right.evaluate.right
} yield {
(l, r)
}
}
}
case class Value(value: Double) extends Evaluate {
def evaluate: Either[EvaluationError,Double] = Right(value)
override def toString(): String = value.toString;
}
case class Add(left: Evaluate, right: Evaluate) extends TwoHandEvaluation {
def evaluate: Either[EvaluationError, Double] = {
for { eval <- evaluateOperands(left, right) } yield { eval._1 + eval._2 }
}
override def toString(): String = "(%s) + (%s)".format(left.toString, right.toString)
}
case class Subtract(left: Evaluate, right: Evaluate) extends TwoHandEvaluation {
def evaluate: Either[EvaluationError, Double] = {
for { eval <- evaluateOperands(left, right) } yield { eval._1 - eval._2 }
}
override def toString(): String = "(%s) - (%s)".format(left.toString, right.toString)
}
case class Multiply(left: Evaluate, right: Evaluate) extends TwoHandEvaluation {
def evaluate: Either[EvaluationError, Double] = {
for { eval <- evaluateOperands(left, right) } yield { eval._1 * eval._2 }
}
override def toString(): String = "(%s) * (%s)".format(left.toString, right.toString)
}
case class Divide(left: Evaluate, right: Evaluate) extends TwoHandEvaluation {
def evaluate: Either[EvaluationError, Double] = {
for { eval <- evaluateOperands(left, right) } yield {
if(eval._2 == 0) {
return Left(EvaluationError(
this,
"Tried to divide by zero",
"Right formula was evaluated as zero, hence this error occured"
))
}
eval._1 / eval._2
}
}
override def toString(): String = "(%s) / (%s)".format(left.toString, right.toString)
}
object Main extends App {
val formula = Add(Divide(Subtract(Value(50), Value(10)), Multiply(Value(30), Value(0))), Value(100));
formula.evaluate match {
case Left(e) => {
println("[!] %s".format(e.reason))
println(" Evaluating: %s".format(formula.toString))
println(" Problem: %s".format(e.evaluating.toString))
println(" Why: %s".format(e.cause))
}
case Right(value) => println("Evaluated successfully: " + formula.toString + " = " + value)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment