Solange Sie diese Typen selbst erstellen müssen, gibt es nicht viel. Aber sobald Sie den Compiler das Zeug für Sie machen, wird es viel nützlicher sein.
Bevor ich dies zeigen, lassen Sie uns Peano aritmetic in etwas zu repräsentieren kürzer eine Art und Weise ändern:
sealed abstract class List[+H, N <: Num](val size: N) {
def ::[T >: H](value: T): List[T, Succ[N]] = Cons(value, this)
}
case object Nil extends List[Nothing, Zero.type](Zero)
case class Cons[+H, N <: Num](head: H, tail: List[H, N]) extends List[H, Succ[N]](Succ(tail.size))
type ::[+H, N <: Num] = Cons[H, N]
Wenn Sie:
sealed trait Num
case object Zero extends Num
case class Succ[N <: Num](num: N) extends Num
Sie dann die Liste mit einer Größe zum Zeitpunkt der Kompilierung bekannt schaffen könnte überprüfen sie die Art von etw mit sych Liste erstellt wird es in seiner Art Größe codiert haben:
val list = 1 :: 2 :: 3 :: 4 :: Nil // List[Int, Succ[Succ[Succ[Succ[Zero.type]]]]] = Cons(1,Cons(2,Cons(3,Cons(4,Nil))))
Das nächste, was Sie versuchen könnten, wäre die Verwendung von implicits, um etwas zu überprüfen, z.
trait EvenNum[N <: Num]
implicit val zeroIsEven = new EvenNum[Zero.type] {}
implicit def evenNPlusTwo[N <: Num](implicit evenN: EvenNum[N]) = new EvenNum[Succ[Succ[N]]] {}
Damit Sie, dass eine Operation nur durchgeführt werden könnte erzwingen könnte, wenn implizite Beweise geliefert werden könnten:
def operationForEvenSizeList[T, N <: Num](list: List[T, N])(implicit ev: EvenNum[N]) = {
// do something with list of even length
}
operationForEvenSizeList(1 :: 2 :: Nil) // ok
operationForEvenSizeList(1 :: 2 :: 3 :: Nil) // compiler error
Soweit ich wahre Macht der Typ-Level-Programmierung kann sagen, in Scala erscheint, wenn Sie beginnen mit der Verwendung von implicits, um neue Typen zu erstellen: solche, die Sie für den impliziten Beweis verwenden könnten, die Typklassenableitung und das Entfernen einiger Strukturtypen.
Eine Bibliothek, die viel mit generischer Programmierung hilft, ist Shapeless. Ich glaube, es wird eine lustige Sache für Sie sein, mit zu arbeiten, sobald Sie eine Übung oder zwei mit einer Typklassenableitung mit implicits machen werden.
Zurück zu Ihrem Code: Sie könnten einige implitits bereitstellen, die Instanzen Ihrer Klasse für Sie generieren und bereitstellen würden. Neben der Erstellung einer neuen Klasse würde dieser Code auch etwas anderes tun, z. Kombinieren Sie Listen von Elementen, die Sie in diesen Klassen hinzufügen würden, oder stellen Sie eine Umwandlung von PeanoNumType in Int bereit, oder fügen Sie einige Vergleichselemente hinzu, die während der Kompilierungszeit usw. arbeiten. Sky ist das Limit.