Scala - корень ковариантной иерархии типов - PullRequest
2 голосов
/ 17 июня 2011

Следующий класс Scala:

class Foo[+T <: Bar] extends FooBase ...

эффективно определяет иерархию типов, в качестве корня которой используется Foo [Bar] - т. Е. Любой допустимый Foo [X] будет назначаться значению Foo [Bar] илипеременная:

val v1: Foo[Bar] = new Foo[SubBar1]();
val v2: Foo[Bar] = new Foo[SubBar2]();

FooBase еще выше и может также подразумевать объекты, которые не являются Foo - следующее показывает проблему:

class Trouble extends FooBase ...
val iOnlyWantFooHere: FooBase = new Trouble();

... а также FooBase не знает овведите T, поэтому его члены не могут его указать, и мне придется переопределить эти определения в Foo, чтобы специализировать их:

class FooBase {
  def ohNoIDontKnowTheType: Bar;
}

class Foo[+T <: Bar] extends FooBase {
  override def ohNoIDontKnowTheType: T = ...;
}

Есть другие способы обойти эту проблему, но суть должна быть ясна.

Наконец, мой настоящий вопрос заключается в том, что является корнем следующей иерархии:

class Foo[+T <: Foo[T]] extends FooBase ...

Опять же, не говорите мне FooBase, потому что это не так.Да, я мог бы вставить другой класс между ними специально для этой цели, но это все еще не верный ответ, как указано выше.

Scala не нравится просто Foo (без параметра типа), и этоне Foo[_], так как тогда доступ к методам, возвращающим значение типа параметра типа, фактически будет Any, а не Foo.Конечно, мы не можем сделать Foo[Foo] либо, так как в нем также отсутствует параметр типа для второго, а Foo[Foo[_]] или Foo[Foo[Foo[Foo[_]]] только дает нам столько уровней.

Есть ли ответ вообще илиScala не поддерживает это?

Заранее спасибо!

1 Ответ

5 голосов
/ 17 июня 2011

Как насчет Foo[_ <: Foo[_]]?Который, кстати, я упомянул в своем ответе на другой ваш вопрос.Или вы могли бы написать это так:

type Base = Foo[t] forSome { type t <: Foo[t] }
...