【问题标题】:Structural type refinement and type equality结构类型细化和类型相等
【发布时间】:2014-02-07 13:59:21
【问题描述】:

当应用于类型改进时,我偶然发现了 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 进一步细化它会 产生与我在 Base 中定义 foo 相同的类型。

或者换句话说,我希望T1T2 表示完全等价的类型。

在大多数情况下,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?

【问题讨论】:

  • typeOf[T1] <:< typeOf[T2] 反之亦然。
  • 这是一个很好的观察。至少有一些的一致性。另一个很棒的事情是,它至少为我提供了一种解决方法:我可以测试(typeOf[T1] <:< typeOf[T2]) && (typeOf[T2] <:< typeOf[T1])。显然,这仍然感觉像是一个黑客攻击

标签: scala reflection structural-typing


【解决方案1】:

可悲的是,它看起来是这个错误:https://issues.scala-lang.org/browse/SI-8177

从好的方面来说...看起来正在积极地修复它:)

【讨论】:

  • +1 用于向我指出相关的错误。但我不确定这是我遇到的错误。 SI-8177 是关于依赖类型和类型前缀的无效处理。我认为这会影响我上面的代码 sn-p 的唯一方法是因为我的类型别名具有不同的前缀。在 REPL 中确实是这种情况,但是我尝试将所有定义包装在同一个对象中(=> 相同的前缀),但我仍然得到相同的错误。虽然修复 SI-8177 可能会解决我的问题作为副作用。我会在 2.11.0-RC1 发布后尝试,如果修复,我会验证你的答案。
  • 好的,scala 2.11.0-RC1 刚刚发布,所以我尝试了反对它(看到 SI-8177 在 scala 2.11.0-RC1 中被标记为已修复)。该错误肯定仍然存在,因此我怀疑 SI-8177 并未涵盖我所描述的问题。也许是时候开票了。
猜你喜欢
  • 1970-01-01
  • 2014-05-22
  • 2020-04-14
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多