¿Tiene Scala una mejor manera de expresar “tipos genéricos autorrecursivos”?
generics recursion (1)
Hay un lenguaje Java común (visto en Enum
por ejemplo) para declarar una variable de tipo genérico que tiene que coincidir con el tipo derivado real.
class Enum<E extends Enum<E>> {
...
}
O, si es necesario, más argumentos genéricos:
abstract class Foo<T, Actual extends Foo<T, Actual>> {
//now we can refer to the actual type
abstract Actual copy();
}
class Concrete<T> extends Foo<T, Concrete<T>> {
Concrete<T> copy() {...}
}
Las cosas se pueden ver muy rápidamente, así que me imaginé que Scala podría tener algo mejor que una traducción literal de los ejemplos anteriores.
¿Hay alguna forma más elegante de lograr esto?
Una formulación alternativa es utilizar miembros de tipo abstracto:
trait Foo { self =>
type A <: Foo {type A = self.A}
}
Con tu ejemplo:
trait Foo { self =>
type T
type Actual <: Foo {type T = self.T; type Actual = self.Actual}
}
trait Concrete extends Foo { self =>
type T
type Actual = Concrete {type T = self.T}
}
Si bien esta reformulación no es realmente mejor en las declaraciones de rasgo / clase, al usar los rasgos / clases puede ser mucho más terser. (Y que yo sepa, no hay otra manera de reformular los tipos recursivos).