I am new to cats-effect and I am trying to implement the classical expression evaluation using cats-effect. Using eval I would like to return an IO[Double] instead of Double. I have my naive code below but of course it doesnt type check. What is the right way to approach this? (It seems like generally with pattern matching it is difficult with IOs).
import cats.effect._
import cats.effect.unsafe.implicits.global
sealed trait Expression
case class Add(x: Expression, y: Expression) extends Expression
case class Mult(x: Expression, y: Expression) extends Expression
case class Exp(x: Expression) extends Expression
case class Const(x: Double) extends Expression
extension (exp: Expression)
def +(other: Expression) = Add(exp,other)
def *(other: Expression) = Mult(exp,other)
def eval(exp: Expression): IO[Double] = IO{
exp match
case Add(x, y) => eval(x) + eval(y) // This does not type check
case Mult(x, y) => eval(x) * eval(y)
case Exp(x) => scala.math.exp(eval(x))
case Const(x) => x
}
val expression1 = Exp((Const(1) + Const(2)) * Const(9))
@main def main =
println(eval(expression1).unsafeRunSync())