Skip to content

Instantly share code, notes, and snippets.

@mads-hartmann
Created January 23, 2018 15:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mads-hartmann/f6f8430fd768cb457f562bbcc556d55f to your computer and use it in GitHub Desktop.
Save mads-hartmann/f6f8430fd768cb457f562bbcc556d55f to your computer and use it in GitHub Desktop.
GADT Example Translation from OCaml to Scala
// I tried to translate the GADT examples I have in my blog post[1] about GADTs
// from OCaml to Scala.
//
// A direct translation resulted in the code below, but I had to add two asInstanceOf
// so I don't consider this a successful translations.
//
// Any idea how to get rid of the asInstanceOf calls? Is it even possible?
//
// [1]: http://mads-hartmann.com/ocaml/2015/01/05/gadt-ocaml.html
object Main {
sealed trait Value[A]
final case class VBool(value: Boolean) extends Value[Boolean]
final case class VInt(value: Int) extends Value[Int]
sealed trait Expression[A]
final case class Val[A](value: Value[A]) extends Expression[A]
final case class If[A](condition: Expression[Boolean], thn: Expression[A], els: Expression[A]) extends Expression[A]
final case class Eq[A](left: Expression[A], right: Expression[A]) extends Expression[Boolean]
final case class Lt[A : Ordering](left: Expression[A], right: Expression[A]) extends Expression[Boolean]
def eval[A](expression: Expression[A]): A = expression match {
case Val(VBool(b)) => b
case Val(VInt(x)) => x
case Eq(left, right) => eval(left) == eval(right)
case Lt(left , right) => {
val l: A = eval(left).asInstanceOf[A] // 😱 How do I get rid og this
val r: A = eval(right).asInstanceOf[A] // and this?
implicitly[Ordering[A]].lt(l, r)
}
case If(condition, left, right) =>
if (eval(condition)) eval(left)
else eval(right)
}
}
@Shadowfiend
Copy link

I believe you'll want to make lines 27-31:

      case Lt(left: Expression[A] , right: Expression[A]) =>
        val l = eval[A](left)
        val r = eval[A](right)
        implicitly[Ordering[A]].lt(l, r)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment