Уточнение структурного типа и равенство типов

Я наткнулся на загадочное поведение Type.=:= при применении к уточнениям типа. Учитывать:

import reflect.runtime.universe._
type T1 = AnyRef {
  def apply( name: String ): Unit
  def foo: String
}

type Base = { def apply( name: String ): Unit }
type T2 = Base {
  def foo: String
}

Учитывая, что Base является псевдонимом для уточнения типа, я ожидал, что его дальнейшее уточнение путем добавления члена foo даст тот же тип, как если бы я определил foo прямо в Base.

Или, другими словами, я ожидаю, что T1 и T2 обозначают полностью эквивалентные типы.

По большей части, scalac, кажется, согласен. Например, я могу передать экземпляр T2, где ожидается экземпляр T1:

def f( x: T1 ){}
f( null: T2 ) // scalac does not complain here

И наоборот:

def g( x: T2 ){}
g( null: T1 ) // scalac is still happy

Я также могу запросить доказательство T1 =:= T2, и оно тоже отлично компилируется:

implicitly[T1 =:= T2]

Однако при использовании отражения scala я получаю совершенно другие результаты:

scala> typeOf[T1] =:= typeOf[T2]
res2: Boolean = false

Так это ошибка отражения scala (я так думаю) или есть фундаментальная причина (техническая или иная), почему typeOf[T1] =:= typeOf[T2] возвращает false?


person Régis Jean-Gilles    schedule 07.02.2014    source источник
comment
typeOf[T1] <:< typeOf[T2] и наоборот тоже верно.   -  person som-snytt    schedule 07.02.2014
comment
Это хорошее наблюдение. По крайней мере, тогда есть некоторая согласованность. Еще одна замечательная вещь заключается в том, что, по крайней мере, это дает мне обходной путь: я могу просто проверить (typeOf[T1] <:< typeOf[T2]) && (typeOf[T2] <:< typeOf[T1]). Очевидно, что это все еще похоже на взлом, хотя   -  person Régis Jean-Gilles    schedule 07.02.2014


Ответы (1)


К сожалению, это похоже на эту ошибку: https://issues.scala-lang.org/browse/SI-8177

С положительной стороны... похоже, что активно ведутся работы по его исправлению :)

person Kevin Wright    schedule 07.02.2014
comment
+1 за указание мне на связанные ошибки. Но я не уверен, что это ошибка, с которой я столкнулся. SI-8177 касается зависимых типов и недопустимой обработки префиксов типов. Единственный способ, которым я могу думать, что это влияет на мой приведенный выше фрагмент кода, заключается в том, что мои псевдонимы типов имеют разные префиксы. Это действительно так в REPL, но я попытался обернуть все определения в один и тот же объект (=> один и тот же префикс), и все равно получаю ту же ошибку. Однако возможно, что исправление SI-8177 решит мою проблему как побочный эффект. Я попробую с 2.11.0-RC1, когда он выйдет, и, если он будет исправлен, я подтвержу ваш ответ. - person Régis Jean-Gilles; 08.02.2014
comment
OK, scala 2.11.0-RC1 только что был выпущен, так что я попробовал против него (поскольку SI-8177 помечен как исправленный в scala 2.11.0-RC1). Ошибка определенно все еще существует, поэтому, как я и подозревал, SI-8177 не покрывает мою описанную проблему. Может быть, пришло время открыть билет. - person Régis Jean-Gilles; 06.03.2014