observation drôle (récursif) types structurels de Scala
-
30-09-2019 - |
Question
I besoin d'un certain type de structure récursive dans un morceau de code à l'aide de traits et le type de structure comme contrainte de paramètre de type. Il a bien fonctionné, mais plus tard, je l'ai appris Scala ne prend pas en charge les types de structure récursive.
Alors quelqu'un peut me expliquer pourquoi cela fonctionne très bien:
scala> trait Test[M[A] <: { def map[B](f: A => B) : M[B] } ] {}
defined trait Test
et cela ne:
scala> def test[M[A] <: { def map[B](f: A => B) : M[B] } ] = null
<console>:5: error: illegal cyclic reference involving type M
def test[M[A] <: { def map[B](f: A => B) : M[B] } ] = null
La solution
Je pense que c'est un petit problème dans le compilateur. Le code suivant présente le même comportement que votre code initial:
trait Test[M[A] <: { def map: M[A] } ] {}
def test[M[A] <: { def map: M[A] } ] = null
Il en résulte un moment de la compilation d'erreur: «référence cyclique illégale.
Et le code suivant ne pas (dire qu'elle compile bien):
type S[M] = { def map: M }
trait Test[M[A] <: S[M[A]] ] {}
def test[M[A] <: S[M[A]] ] = null
La seule différence est que le typage structurel est appliqué par l'intermédiaire d'un alias de type S ici.
Autres conseils
Le premier extrait de code met également en erreur Scala 2.7.7final:
scala> trait Test[M[A] <: { def map[B](f: A => B) : M[B] } ] {}
<console>:4: error: illegal cyclic reference involving type M
trait Test[M[A] <: { def map[B](f: A => B) : M[B] } ] {}
^
Quelle version de Scala utilisez-vous?