2010-09-04 33 views
24

Necesitaba algún tipo de estructura recursiva en algún fragmento de código usando rasgos y el tipo estructural como restricción de parámetro de tipo. Funcionó bien, pero luego supe que Scala no admite tipos estructurales recursivos.Observación divertida sobre tipos estructurales (recursivos) en Scala

Entonces alguien me puede explicar 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 

Respuesta

6

Creo que esto es un error en el compilador. El código siguiente 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 siguiente código no lo hace (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 la tipificación estructural se aplica a través de un tipo de alias S aquí.

+0

en realidad me gusta la solución con alias de tipo y que incluso funciona para definiciones de funciones. Pero su primer ejemplo se comporta exactamente como el mío, diciendo que el Test-rasgo compila bien. Pero si funciona usando alias tipo, definitivamente debería funcionar sin usarlos también?!? – urso

+0

Sí, creo que hay algunas inconsistencias aquí: debería funcionar con alias de tipo y sin o no debería funcionar en absoluto. Es por eso que creo que esto es un error en el compilador. – michid

+0

¿Tiene un número de rastreador de errores? – soc

0

El primer fragmento de código también tiros 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 usas?

+0

WOrks en Scala 2.8.1 – tstenner

+0

Estoy usando scala 2.8.0 – urso

Cuestiones relacionadas