Jak zaimplementować interpreter „dodaj” w scali?

Sep 27 2020

Wdrażam interpreter scala i mam problem

Mam klasę wartości, jak następuje Value.scala:

case class IntV(value: Int) extends Value

Śledziłem również zajęcia w pliku Expr.scala:

case class IntE(value: Int) extends Expr
case class Add(left: Expr, right: Expr) extends Expr

Kiedy zaimplementowałem interpreter Int w następujący sposób:

case IntE(value)=>IntV(value)

Działało dobrze, ale kiedy zaimplementowałem dodaj interpreter (który dodaje jak 3 + 4 = 7), jak następuje:

case Add(left, right)=>IntV(left)+IntV(right)

Zwraca błąd, który mówi dla zmiennej lewej i prawej, wymaga, Intale znalazł expr.
Co zrobiłem źle? Co mam zrobić, aby otrzymać prawidłowy zwrot?

Odpowiedzi

3 DmytroMitin Sep 27 2020 at 14:31

Powinieneś rekurencyjnie wywoływać interpreter.

Na przykład

sealed trait Value
case class IntV(value: Int) extends Value 

sealed trait Expr
case class IntE(value: Int) extends Expr
case class Add(left: Expr, right: Expr) extends Expr

def interpret(expr: Expr): Value = expr match {
  case IntE(value)      => IntV(value)
  case Add(left, right) => (interpret(left), interpret(right)) match {
    case (IntV(v1), IntV(v2)) => IntV(v1 + v2)
  }
}

interpret(IntE(1)) // IntV(1)
interpret(Add(IntE(3), IntE(4))) // IntV(7)

Lub z określoną metodą +dlaIntV

sealed trait Value
case class IntV(value: Int) extends Value {
  def +(other: IntV): IntV = IntV(value + other.value)
}

sealed trait Expr
case class IntE(value: Int) extends Expr
case class Add(left: Expr, right: Expr) extends Expr

def interpret(expr: Expr): Value = expr match {
  case IntE(value)      => IntV(value)
  case Add(left, right) => (interpret(left), interpret(right)) match {
    case (v1: IntV, v2: IntV) => v1 + v2
  }
}