Scala:特征中的“静态值”?

时间:2018-05-06 17:54:37

标签: scala generic-programming type-systems type-theory singleton-type

让我说我有:

trait X {
  val x: String
}

使用混合,我可以定义一个特征,如

trait XPrinter {
  self: X =>
  def printX: String = "X is: " + x
}

使得实现XPrinter的值/对象实现x并使其printX等方法可以访问X中指定的值,例如x

到目前为止,这么好。

我想知道是否有一种方式具有以下形式的特征:

trait XDependent[T <: X] {
  def printX: String = ???
}

这样XDependent个实例可以访问T.x的值,x假设是一个与类型定义粘合的“静态值”。

现在我明白了为什么T.x无法在XDependent中访问,因为类型子类型X甚至不必实现x的值,而T.x可能是抽象的。

我理解,虽然Scala提供了路径依赖类型,因此可以在XDependent中使用X中定义的抽象类型,如下所示:

trait X {
  type Y //which can be constrained as desired.
}

trait XDependent[T <: X]{
  def foo(v:T#Y)
  def bar: T#Y
}

它不提供相同的值,因为Scala中的类型和值之间存在明显的分离。

现在我遇到了依赖于价值的类型基于文字的类型的想法。我想知道,如上所述,“静态值类型”的概念是否与这些概念和连接有很多重叠。

我还想知道不同语言采用的不同方法,模糊类型和值之间的分离,它们与Scala类型系统的兼容性,以及在集成“静态值”方面的复杂性与类型系统。即,(它们可以)/(如果它们会发生什么)被子类型等覆盖

1 个答案:

答案 0 :(得分:1)

如果您可以放宽XDependent必须为trait的要求,并将其设为abstract class,那么它似乎就像提供单个空值的类型类一样方法x正是您想要的:

以下是您的基本特征X(不含X.x或其他任何内容,不会是&#34;静态&#34;):

trait X

现在您可以定义类型类HasStaticX[T],以确保对于类型T我们可以提供一些字符串x

trait HasStaticX[T] {
  def x: String
}

然后你可以像这样使用它:

abstract class XDependent[T <: X : HasStaticX] {
  def printX: String = implicitly[HasStaticX[T]].x
}

HasStaticX的作用主要是构建一个编译时部分函数,​​该函数可以采用类型T并生成与x关联的字符串值T。所以,在某种程度上,它类似于一个获取类型和返回值的函数。如果这是你想要的,那么就不需要做任何事情来集成静态值&#34;它只适用于当前非实验性主流版本的Scala。

&#34;价值相关类型&#34;完全相反:那些基本上是&#34;功能&#34;将类型分配给值。