Lustige Beobachtung über (rekursiv) Strukturtypen in Scala
-
30-09-2019 - |
Frage
Ich brauchte einige rekursive Strukturtyp in irgendeinem Stück Code mit Eigenschaften und der Strukturtyp als Typ Parameterbedingung. Es funktionierte gut, aber später habe ich gelernt, Scala nicht rekursive Strukturtypen unterstützt.
So kann jemand mir erklären, warum das gut funktioniert:
scala> trait Test[M[A] <: { def map[B](f: A => B) : M[B] } ] {}
defined trait Test
und dies nicht:
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
Lösung
Ich denke, dies ist ein Fehler im Compiler ist. Der folgende Code zeigt das gleiche Verhalten wie Ihre ursprünglichen Code:
trait Test[M[A] <: { def map: M[A] } ] {}
def test[M[A] <: { def map: M[A] } ] = null
Es führt zu einem Kompilierung-Fehlern: ‚illegale zyklische Referenz‘.
Und der folgende Code nicht (das heißt es kompiliert fein):
type S[M] = { def map: M }
trait Test[M[A] <: S[M[A]] ] {}
def test[M[A] <: S[M[A]] ] = null
Der einzige Unterschied besteht darin, dass strukturelle Typisierung angewandt wird über eine Art Alias ??hier S.
Andere Tipps
Der erste Code-Snippet wirft auch Fehler in 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] } ] {}
^
Welche Version von Scala tun Sie verwenden?