Shapeless Witness 以及它如何给出实际的单例类型

Som*_*ame 5 scala generic-programming type-level-computation shapeless

我试图以无形的方式理解单例类型,并面临对单例类型编译时类型的误解。下面是一个例子:

val x: Witness.`120`.T = 120.narrow
Run Code Online (Sandbox Code Playgroud)

它工作正常,但这种结构看起来很不寻常。什么是Witness.120?在 IDE 中,它指向一些宏函数selectDynamic

def selectDynamic(tpeSelector: String): Any = macro SingletonTypeMacros.witnessTypeImpl
Run Code Online (Sandbox Code Playgroud)

具有编译时类型Any和由施工判断Witness.120.T一个type部件T。这看起来很神奇......当一个人写下这样的东西时,任何人都可以解释一下实际发生的事情:

val x: Witness.`120`.T = //...
Run Code Online (Sandbox Code Playgroud)

Krz*_*sik 5

Witness创建所谓的基于文字的单例类型文字类型意味着它是一种只能接受一个值的类型。

所以如果你创建一个像这样的函数:

def f(x: Witness.`120`.T) = x
Run Code Online (Sandbox Code Playgroud)

它只接受整数120,但不接受121

由于Scala 2.13 文字类型已集成到该语言中,因此您可以将其简单地编写为:

def f(x: 120) = x
Run Code Online (Sandbox Code Playgroud)

函数narrow将值的类型120从一般类型缩小Int为文字类型120