Esto se hace con la herencia en Scala (tal vez por desgracia, ya que es más prolija)
sealed trait Expr
case class Val(s: String) extends Expr
case class Integer(i: Int) extends Expr
case class Lower(left: Expr, right: Expr) extends Expr
case class Greater(left: Expr, right: Expr) extends Expr
...
puede escribir más
sealed trait Expr[A]
case class Val(s: String) extends Expr[String]
case class Integer(i: Int) extends Expr[Int]
case class Lower[X](left: Expr[X], right: Expr[X])(implicit val ordering: Ordering[X]) extends Expr[Boolean]
coincidencia de patrones con
def valueOf[A](expr: Expr[A]) : A = expr match {
case Val(s) => s
case Integer(i) => i
case l @ Lower(a,b) => l.ordering.lt(valueOf(a), valueOf(b))
...
}
valueOf haría probablemente sea mejor como un método en Expr
sealed trait Expr[A] {def value: A}
case class Val(value: String) extends Expr[String]
case class Integer(value: Int) extends Expr[Int]
case class Lower[X: Ordering](left: Expr[A], right: Expr[A]) extends Expr[Bool] {
def value = implicitly[Ordering[X]].lt(left.value, right.value)
}
...
realmente rápido y realmente respondió mi pregunta ¡Gracias! –