带有猫效应的表达式评估(Add、Mult 等)

问题描述 投票:0回答:1

我是 cats-effect 的新手,我正在尝试使用 cats-effect 实现经典表达式评估。使用 eval 我想返回一个 IO[Double] 而不是 Double。我在下面有我的天真代码,但当然它没有类型检查。处理这个问题的正确方法是什么? (似乎通常使用模式匹配很难使用 IO)。

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())
scala scala-cats io-monad cats-effect
1个回答
0
投票

IO
是一个单子。尝试理解

def eval(exp: Expression): IO[Double] =
  exp match
    case Add(x, y)  => for {
      x1 <- eval(x)
      y1 <- eval(y)
    } yield x1 + y1
    case Mult(x, y) => for {
      x1 <- eval(x)
      y1 <- eval(y)
    } yield x1 * y1
    case Exp(x)     => for {
      x1 <- eval(x)
    } yield scala.math.exp(x1)
    case Const(x)   => IO(x)

或应用语法

import cats.syntax.apply.given

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(x)
© www.soinside.com 2019 - 2024. All rights reserved.