【问题标题】:Are path-dependent types type projections?路径相关类型是类型投影吗?
【发布时间】:2012-05-12 02:22:27
【问题描述】:

我现在正在深入阅读 Scala。以下是本书的摘录:

所有依赖路径的类型都是类型投影。一个依赖路径的类型foo.Bar被重写 编译器为foo.type#Bar...

在 Scala 中,所有类型引用都可以编写为针对命名实体的项目。 scala.String 类型是scala.type#String 的简写,其中名称scala 指的是包scala,类型String 由scala 包上的String 类定义。

显然,没有 scala.String 类,但我无法使用 Null 重现这一点。

scala> type N = scala.type#Null
<console>:7: error: type mismatch;
 found   : type
 required: AnyRef
       type N = scala.type#Null

所以,我的问题如下。路径相关类型是类型投影吗?它只是内部编译器表示还是可以用scala代码表示?

【问题讨论】:

    标签: scala types projection path-dependent-type


    【解决方案1】:

    这是一个快速的 REPL 会话,它确认了 Josh 所写的内容,

    scala> class Foo { type T = String }
    defined class Foo
    
    scala> val foo = new Foo
    foo: Foo = Foo@10babe8
    
    scala> implicitly[foo.type#T =:= foo.T]
    res0: =:=[foo.T,foo.T] = <function1>
    

    scala.type#Null 示例的问题在于前缀 scala 是包前缀,而不是值的稳定标识符。可以说它应该是后者,但不幸的是它不是……这是 Scala 包的语义和 Scala 对象(在模块的意义上)之间挥之不去的不匹配。

    【讨论】:

    • 但根据 SLS §3.1 A path is one of the following... p.x where p is a path and x is a stable member of p. Stable members are packages or... A stable identifier is a path which ends in an identifier. scala.Null 是稳定标识符。对吗?
    • 不,所有稳定标识符都是值或包:scala.Null 指定类型而不是值。 scala 是一个稳定的标识符,但正如您所观察到的,它是一个包而不是一个对象,它的行为是在运算符 .type 中形成的单例类型与我在回答中给出的示例 foo 不同。
    • 哦,现在,我终于明白这一切都与.type 行为有关。花了很多时间来理解它。非常感谢:)
    • @MilesSabin 很抱歉打扰您,但我对implicitly[foo.type#T =:= foo.T] 行有疑问,=:= 用于判断两种类型是否相同,因此结果是布尔值,但隐含方法需要一个 T 作为类型参数,所以为什么该行有效并以 =:=[foo.T,foo.T] 的形式返回一个 function1。
    • @AllenChou 不,这是一个函数,而不是布尔值。 foo.type#T =:= foo.T 是一个中缀类型,它脱糖为=:=[foo.type#T, foo.T],其中extends (foo.type#T) =&gt; foo.T。阅读Predef 文档。返回的隐含证据是=:=.tpEquals[foo.T]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-22
    • 1970-01-01
    • 2021-09-19
    • 2021-10-27
    • 1970-01-01
    • 1970-01-01
    • 2012-09-17
    相关资源
    最近更新 更多