Skip to content

Instantly share code, notes, and snippets.

@regiskuckaertz
Created July 14, 2021 09:52
Show Gist options
  • Save regiskuckaertz/6067235afa9b018a9ae5aa4584b5aa07 to your computer and use it in GitHub Desktop.
Save regiskuckaertz/6067235afa9b018a9ae5aa4584b5aa07 to your computer and use it in GitHub Desktop.
Basic ADT stuff
/*
L :== integer
| L + L
| L * L
| (L)
| L / L
*/
// initial encoding
sealed trait Language { left =>
def add(right: Language): Language = LPlus(left, right)
def mul(right: Language): Language = LMult(left, right)
}
case class LInt(value: Int) extends Language
case class LPlus(left: Language, right: Language) extends Language
case class LMult(left: Language, right: Language) extends Language
case class LDivMod(left: Language, right: Language) extends Language
case class LBrack(term: Language) extends Language
val x = LInt(5) add LInt(10) mul LInt(2)
sealed trait Result { left =>
def +(right: Result): Result =
(left, right) match {
case (RInt(l), RInt(r)) => RInt(l + r)
case (RTupl((l, _)), RInt(r)) => RInt(l + r)
case _ => RInt(0)
}
def *(right: Result): Result =
(left, right) match {
case (RInt(l), RInt(r)) => RInt(l * r)
case (RTupl((l, _)), RInt(r)) => RInt(l * r)
case _ => RInt(0)
}
def divMod(right: Result): Result =
(left, right) match {
case (RInt(l), RInt(r)) => RTupl((l / r, l % r))
case _ => RInt(0)
}
}
case class RInt(value: Int) extends Result
case class RTupl(value: (Int, Int)) extends Result
def eval(term: Language): Result =
term match {
case LInt(value) => RInt(value)
case LPlus(left, right) => eval(left) + eval(right)
case LMult(left, right) => eval(left) * eval(right)
case LBrack(term) => eval(term)
case LDivMod(l, r) => eval(l) divMod eval(r)
}
eval(LDivMod(LInt(5), LInt(2)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment