Смешные наблюдения о (рекурсивных) структурных типах в Scala
Мне нужен рекурсивный структурный тип в некотором фрагменте кода с использованием признаков и структурного типа в качестве ограничения параметра типа. Он работал нормально, но позже я узнал, что Scala не поддерживает рекурсивные структурные типы.
Так может кто-нибудь объяснить мне, почему это прекрасно работает:
scala> trait Test[M[A] <: { def map[B](f: A => B) : M[B] } ] {}
defined trait Test
и это не:
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
Ответы
Ответ 1
Я думаю, что это сбой в компиляторе. Следующий код демонстрирует то же поведение, что и ваш исходный код:
trait Test[M[A] <: { def map: M[A] } ] {}
def test[M[A] <: { def map: M[A] } ] = null
Это приводит к ошибке времени компиляции: "незаконная циклическая ссылка".
И следующий код не делает (т.е. компилируется):
type S[M] = { def map: M }
trait Test[M[A] <: S[M[A]] ] {}
def test[M[A] <: S[M[A]] ] = null
Единственное отличие заключается в том, что структурная типизация применяется через псевдоним типа S здесь.
Ответ 2
Первый фрагмент кода также вызывает ошибку в 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] } ] {}
^
Какую версию Scala вы используете?