// `Tuple[Natural, Natural]`
case class Integer(pos: Natural, neg: Natural) { self =>
def unary_- = copy(neg, pos)
def + (that: Integer): Integer = Integer(self.pos + that.pos, self.neg + that.neg)
def - (that: Integer): Integer = this + (-that)
def * (that: Integer): Integer = Integer(
self.pos * that.pos + self.neg * that.neg,
self.neg * that.pos + self.pos * that.neg)
def toInt: Int = pos.toInt - neg.toInt
override def toString = toInt.toString
}
object Integer {
def zero = Integer(Natural.zero, Natural.zero)
def one = Integer(Natural.zero.succ, Natural.zero)
def of(v: Int): Integer =
if (v < 0) of(v + 1) - one
else if (v > 0) of(v - 1) + one
else zero
}
trait List[A] { self =>
def fold[Z](empty: => Z, cons: Z => A => Z): Z
def :: (head: A): List[A] = new List[A] {
def fold[Z](empty: => Z, cons: Z => A => Z): Z = self.fold(cons(head, empty), cons)
}
}
object List {
def Nil[A]: List[A] = new List[A] {
def fold[Z](empty: => Z, cons: Z => A => Z): Z = empty
}
}
-
Boolean
trait Boolean { def fold[Z](left: => Z, right: => Z): Z }
-
Option
trait Option[A] { def fold[Z](empty: => Z, some: A => Z): Z }
-
Either
trait Either[A, B] { def fold[Z](left: A => Z, right: B => Z): Z }
-
Tuple
trait Tuple[A, B] { def apply[Z](abz: A => B => Z): Z }
-
Rational
type Rational = Tuple[Integer, Integer]