| 1 | package metascala |
|---|
| 2 | |
|---|
| 3 | object Integers { |
|---|
| 4 | import Utils._ |
|---|
| 5 | import Visitables._ |
|---|
| 6 | import Addables._ |
|---|
| 7 | import Subtractables._ |
|---|
| 8 | |
|---|
| 9 | trait NatVisitor extends TypeVisitor { |
|---|
| 10 | type Visit0 <: ResultType |
|---|
| 11 | type VisitSucc[Pre <: Nat] <: ResultType |
|---|
| 12 | } |
|---|
| 13 | |
|---|
| 14 | trait IntVisitor extends NatVisitor { |
|---|
| 15 | type VisitNeg[Pos <: Nat] <: ResultType |
|---|
| 16 | } |
|---|
| 17 | |
|---|
| 18 | sealed trait MInt extends Visitable[IntVisitor] with Addable with Subtractable { |
|---|
| 19 | type AddType = MInt |
|---|
| 20 | type SubType = MInt |
|---|
| 21 | type Add[I <: MInt] <: MInt |
|---|
| 22 | type Neg <: MInt |
|---|
| 23 | type Succ <: MInt |
|---|
| 24 | type Pre <: MInt |
|---|
| 25 | type Sub[I <: MInt] <: MInt |
|---|
| 26 | } |
|---|
| 27 | |
|---|
| 28 | sealed trait Nat extends MInt { |
|---|
| 29 | type Accept[V <: IntVisitor] = AcceptNatVisitor[V] |
|---|
| 30 | type AcceptNatVisitor[V <: NatVisitor] <: V#ResultType |
|---|
| 31 | } |
|---|
| 32 | |
|---|
| 33 | final class _0 extends Nat { |
|---|
| 34 | type Add[I <: MInt] = I |
|---|
| 35 | type AcceptNatVisitor[V <: NatVisitor] = V#Visit0 |
|---|
| 36 | type Neg = _0 |
|---|
| 37 | type Succ = MSucc[_0] |
|---|
| 38 | type Pre = Succ#Neg |
|---|
| 39 | type Sub[I <: MInt] = I#Neg |
|---|
| 40 | } |
|---|
| 41 | |
|---|
| 42 | sealed trait Pos extends Nat |
|---|
| 43 | |
|---|
| 44 | final class MSucc[P <: Nat] extends Pos { |
|---|
| 45 | type This = MSucc[P] |
|---|
| 46 | type Add[N <: MInt] = P#Add[N]#Succ |
|---|
| 47 | type AcceptNatVisitor[V <: NatVisitor] = V#VisitSucc[P] |
|---|
| 48 | type Neg = MNeg[This] |
|---|
| 49 | type Pre = P |
|---|
| 50 | type Succ = MSucc[This] |
|---|
| 51 | type Sub[I <: MInt] = Add[I#Neg] |
|---|
| 52 | } |
|---|
| 53 | |
|---|
| 54 | final class MNeg[N <: Pos] extends MInt { |
|---|
| 55 | type Add[N <: MInt] = N#Add[N#Neg]#Neg |
|---|
| 56 | type Accept[V <: IntVisitor] = V#VisitNeg[N] |
|---|
| 57 | type Neg = N |
|---|
| 58 | type Succ = N#Pre#Neg |
|---|
| 59 | type Pre = N#Succ#Neg |
|---|
| 60 | type Sub[I <: MInt] = Add[I#Neg] |
|---|
| 61 | } |
|---|
| 62 | |
|---|
| 63 | type _1 = MSucc[_0] |
|---|
| 64 | type _2 = MSucc[_1] |
|---|
| 65 | type _3 = MSucc[_2] |
|---|
| 66 | type _4 = MSucc[_3] |
|---|
| 67 | type _5 = MSucc[_4] |
|---|
| 68 | type _6 = MSucc[_5] |
|---|
| 69 | type _7 = MSucc[_6] |
|---|
| 70 | type _8 = MSucc[_7] |
|---|
| 71 | type _9 = MSucc[_8] |
|---|
| 72 | type _10 = MSucc[_9] |
|---|
| 73 | |
|---|
| 74 | val _0 = new _0 |
|---|
| 75 | val _1 = new _1 |
|---|
| 76 | val _2 = new _2 |
|---|
| 77 | val _3 = new _3 |
|---|
| 78 | val _4 = new _4 |
|---|
| 79 | val _5 = new _5 |
|---|
| 80 | val _6 = new _6 |
|---|
| 81 | val _7 = new _7 |
|---|
| 82 | val _8 = new _8 |
|---|
| 83 | val _9 = new _9 |
|---|
| 84 | val _10 = new _10 |
|---|
| 85 | |
|---|
| 86 | implicit val _0ToInt = TypeToValue[_0, Int](0) |
|---|
| 87 | implicit def succToInt[P <: Nat](implicit v : TypeToValue[P, Int]) = TypeToValue[MSucc[P], Int](1 + v.value) |
|---|
| 88 | |
|---|
| 89 | } |
|---|