Scala 3/Dotty中如何编写接收唯一路径值的类型构造器WOf?
在Scala 3中实现接收单例路径类型的类型构造器
问题核心
你想定义一个通用类型构造器WOf[T],传入Col[_]的单例对象类型时返回该对象内部的Wrapper类型,但直接用T#Wrapper会报错,因为编译器认为T不是合法的路径类型。
正确实现:用匹配类型(Match Types)
Scala 3的匹配类型是解决这类问题的标准方案,还能写得更通用,不用枚举所有Col的子类:
sealed trait Col[V] { trait Wrapper } object Col1 extends Col[Int] object Col2 extends Col[Double] // 通用的类型构造器 type WOf[T <: Col[_] with Singleton] = T match { case c: Col[_] => c.Wrapper }
这个写法会自动匹配所有Col[_]的单例类型,返回对应内部的Wrapper,不需要你逐个列出Col1、Col2。
为什么T#Wrapper行不通?
Scala的类型投影#要求左侧是稳定类型——也就是能对应到一个具体路径的类型(比如Col1.type这种单例对象类型)。虽然你给T加了with Singleton约束,说明T是单例类型,但在定义WOf的时候,编译器还不知道T具体对应哪个路径,所以无法直接用T#Wrapper。
而匹配类型通过模式匹配,把T绑定到具体的Col[_]实例类型,此时c是稳定的路径,就能合法访问c.Wrapper。
和值级多态函数的关联
你提到的def wOf[T <: Col[_]](v: T): v.Wrapper = ???是值级别的依赖类型方法,这里v.Wrapper是依赖路径类型——它依赖的是具体的参数v(值层面的路径),而不是类型参数T。这和类型构造器的场景有区别:
- 值级方法里,
v是具体的实例,所以v.Wrapper是合法的路径类型。 - 类型构造器里,
T是类型参数,即使加了Singleton约束,编译器在定义时无法确定T的具体路径,必须用匹配类型来“解析”。
如果要让类型构造器和这个值级方法对应,可以这样写:
def wOf[T <: Col[_] with Singleton](v: T): WOf[T] = ???
此时WOf[T]就等价于v.Wrapper,完全符合你的需求。
内容的提问来源于stack exchange,提问作者tribbloid
相关产品推荐
相关产品推荐

