基于Cats-Effect实现表达式求值(加法、乘法等)的问题咨询
解决Cats-Effect中表达式求值IO[Double]的类型检查问题
你的代码核心问题是直接对IO[Double]类型使用普通数值运算符,以及错误地用IO{}包裹整个IO组合逻辑。下面是修正后的完整实现:
import cats.effect._ import cats.effect.unsafe.implicits.global import cats.implicits._ // 导入Cats语法扩展,支持mapN等组合器 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] = exp match case Add(x, y) => (eval(x), eval(y)).mapN(_ + _) case Mult(x, y) => (eval(x), eval(y)).mapN(_ * _) case Exp(x) => eval(x).map(scala.math.exp) case Const(x) => IO.pure(x) val expression1 = Exp((Const(1) + Const(2)) * Const(9)) @main def main = println(eval(expression1).unsafeRunSync())
关键修改说明:
- 移除外层
IO{}包裹:原代码中IO{...}要求代码块返回Double,但模式匹配分支实际返回IO[Double],类型完全不匹配。直接让eval的模式匹配返回IO[Double]即可。 - 用
mapN组合IO值:Add和Mult分支里,eval(x)和eval(y)都是IO[Double],不能直接用+/*。(eval(x), eval(y)).mapN(_ + _)可以并行执行两个IO操作,再对结果做数值运算。 - 用
map转换IO内部值:Exp分支中,scala.math.exp需要Double类型参数,所以用eval(x).map(scala.math.exp)先提取IO内部的数值,再应用指数函数。 - 用
IO.pure包装纯值:Const分支的x是纯Double值,需要用IO.pure(x)包装成IO[Double],保证所有分支返回类型一致。
内容的提问来源于stack exchange,提问作者Lukas Tycho
相关产品推荐
相关产品推荐

