在Scala 3中,为什么有时可以进行非Assert类型赋值?

9wbgstp7  于 2023-05-17  发布在  Scala
关注(0)|答案(2)|浏览(207)

Scala 3是一种非 predicate 语言,通常不可能将更高的类型分配给正常类型(有触发吉拉德悖论的风险),但在现实中,一些类型分配似乎可以绕过这一规则:

trait Vec[T]

      type VV1 = Vec // paradox!

      type VV2 = [T] =>> Vec[T] // no paradox?

最后两行有什么区别?为什么第二种可能?

798qvoo8

798qvoo81#

第二行是可能的,因为语言作者决定类型别名可以包含类型构造函数以保持一致性。如果List是一个类型,尽管它不是一个正确的类型,那么如果我们想要保持一致,它可以是一个类型别名。如果函数可以被修饰、部分应用或传递,那么类型也可以。

trait Vec[T]

type VV1 = Vec // not! a paradox, but shorthand for type VV1 = [T] =>> Vec[T]

第二行等于第三行:
参数化类型定义

type T[X] = R

被认为是一个非参数化定义的简写,右边是一个lambda类型:

type T = [X] =>> R

一个部分应用的类型构造函数,如List,被假定为等价于它的eta扩展。即List = [X] =>> List[X]。这允许将类型构造函数与类型lambda进行比较。
有关详细信息,请参见specification

n3ipq98p

n3ipq98p2#

找到原因:在Scala中,高阶类型不能与类型名的语法相关联,0-type和2-type都可以分配给类型名。它们只是在食用时的行为不同:

type VV2 = [T <: AnyVal] =>> Vec[T] // no paradox?

      type NN = List[VV2] // still paradox!
      // : Type argument VV2 does not have the same kind as its bound

关于第一个定义type VV = Vec,由于某些解析歧义,它可能被编译器禁止

相关问题