Смешное наблюдение о (рекурсивных) структурных типах в Scala

StackOverflow https://stackoverflow.com/questions/3643699

  •  30-09-2019
  •  | 
  •  

Вопрос

Мне нужен был какой-то рекурсивный структурный тип в каком-то куске кода, используя с чертами и структурным типом в качестве ограничения параметра типа. Он работал нормально, но позже я узнал 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
Это было полезно?

Решение

Я думаю, что это глюк в компиляторе. Следующий код демонстрирует то же поведение, что и ваш исходный код:

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

Единственное отличие состоит в том, что структурное набрав применяется через псевдоним типа.

Другие советы

Фрагмент первого кода также бросает ошибку в 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 вы используете?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top