observación divertida sobre tipos estructurales (recursiva) en Scala
-
30-09-2019 - |
Pregunta
I necesitaba algún tipo estructural recursiva en alguna pieza de código usando con rasgos y el tipo estructural como restricción parámetro de tipo. Funcionó bien, pero más tarde me enteré de Scala no es compatible con los tipos estructurales recursivos.
Entonces, ¿puede alguien me explique por qué esto funciona bien:
scala> trait Test[M[A] <: { def map[B](f: A => B) : M[B] } ] {}
defined trait Test
y esto no:
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
Solución
creo que esto es un problema técnico en el compilador. El siguiente código muestra el mismo comportamiento que el código inicial:
trait Test[M[A] <: { def map: M[A] } ] {}
def test[M[A] <: { def map: M[A] } ] = null
Es el resultado de un error de tiempo de compilación: 'referencia cíclico ilegal'.
Y el código siguiente no (es decir, que compila bien):
type S[M] = { def map: M }
trait Test[M[A] <: S[M[A]] ] {}
def test[M[A] <: S[M[A]] ] = null
La única diferencia es que se aplica la tipificación estructural a través de un tipo de alias está aquí.
Otros consejos
El primer código también snippet lanza error en 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] } ] {}
^
¿Qué versión de Scala se utilizan?