object Main {
sealed abstract class Nat
case class Z() extends Nat
case class S(x:Nat) extends Nat
def add(x: Nat, y: Nat): Nat = (x, y) match {
case (_, Z()) => x
case (Z(), _) => y
case (S(a), _) => add(a, S(y))
}
def mult(x: Nat, y: Nat): Nat = {
def sub(x: Nat, y: Nat, sum: Nat): Nat = x match {
case Z() => sum
case S(a) => sub(a, y, add(y, sum))
}
sub(x, y, Z())
}
def main(args: Array[String]) {
println(Z())
println(S(S(Z()))) // automatically derived Show
val one = S(Z())
val two = S(S(Z()))
val three = S(S(S(Z())))
println(add(one, two))
println(add(one, two) == three) // true
println(mult(two, three)) // six
}
}