Имеет ли Scala лучший способ выражения "саморекурсивных общих типов"? - программирование
Подтвердить что ты не робот

Имеет ли Scala лучший способ выражения "саморекурсивных общих типов"?

Существует общая идиома Java (например, в Enum), чтобы объявить типичную переменную типа, которая должна соответствовать фактическому производному типу.

class Enum<E extends Enum<E>> {
...
}

или, если необходимо, более общие аргументы:

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() {...}
}

Вещи могут быть очень подробными очень быстро, поэтому я представил себе, что Scala может иметь что-то приятнее, чем буквальный перевод приведенных выше примеров.

Есть ли еще более элегантные способы достижения этого?

4b9b3361

Ответ 1

Альтернативная формулировка заключается в использовании элементов абстрактного типа:

trait Foo { self => 
  type A <: Foo {type A = self.A}
}

В вашем примере:

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}
}

В то время как эта переформулировка не очень приятна в объявлениях признака/класса, при использовании признаков/классов это может быть много. (И, насколько я знаю, нет другого способа переформулировать рекурсивные типы).