Scala ne prend pas en charge les alias de types récursifs sans arguments supplémentaires du compilateur (spécifiquement, -Yrecursion
). Ceci est en partie pour garder le vérificateur de type au moins quelque peu dans le domaine de la décidabilité (bien que, comme nous l'avons découvert, le système de type est Turing Complete même sans alias de type récursif, donc cela n'a pas beaucoup d'importance).
La manière correcte de faire ce genre de choses est d'utiliser une classe de type. Scala les encode comme des limites de vue implicites. Par exemple :
trait Addable[A] {
def zero: A
def add(x: A, y: A): A
}
implicit object IntAddable extends Addable[Int] {
def zero = 0
def add(x: Int, y: Int) = x + y
}
implicit object DoubleAddable extends Addable[Double] {
def zero = 0
def add(x: Double, y: Double) = x + y
}
// ...
def sum[A](x: A, y: A)(implicit tc: Addable[A]) = tc.add(x, y)
Et bien sûr, cela vous permet aussi de faire des choses fantaisistes comme additionner le contenu d'un fichier Seq
d'une manière sûre :
implicit def summableSeqSyntax[A](seq: Seq[A])(implicit tc: Addable[A]) = new {
def sum = seq.foldLeft(tc.zero)(tc.add)
}
List(1, 2, 3, 4).sum // => 10
List(true, false).sum // does not compile
Il est intéressant de noter que Scala 2.8 a quelque chose de très proche de cela avec la fonction Numeric
typeclass.