gpt4 book ai didi

scala - 类型别名中的方差注释

转载 作者:行者123 更新时间:2023-12-03 03:43:59 26 4
gpt4 key购买 nike

最近我注意到方差注释可以在类型别名中使用。以下是来自 Predef 的示例:

type Function[-A, +B] = Function1[A, B]

我开始思考它可以用在哪里。显然,您不能将方差更改为相反,或者使不变类型表现为协变或逆变。编译器会抛出一个错误,像这样

scala> type BrokenFunc[+T, -R] = Function1[T, R]
<console>:7: error: covariant type T occurs in contravariant position in type
[+T, -R]T => R of type BrokenFunc

但是,您可以使某些变体类型表现得像不变的(至少,编译器不会反对这一点)。因此,我尝试制作 List

的不变版本
scala> type InvList[T] = List[T]
defined type alias InvList

但是这个新的不变 List 的行为仍然就像它的原始协变版本一样:

scala> val l: InvList[String] = List("foo")
l: InvList[String] = List(foo)

scala> val anyList: InvList[Any] = l
anyList: InvList[Any] = List(foo)

那么,我缺少什么?类型别名中差异注释的目的是什么?您能否给出一个带有方差注释的类型别名的示例,它将与原始类型不同。

最佳答案

所以,我不确定,但我将提供一个可能的解释。

Scala 中的类型别名相当“弱”;他们并没有完全创建新类型,只是编写旧类型(以及新的路径依赖类型)的新方法;这意味着如果您定义

type InvList[T] = List[T]

并写下InvList[T] ,就像你写的 List[T] 一样;这就是为什么InvList[Int] <: InvList[Any] ,因为重写后,这只是 List[Int] <: List[Any] 。我实际上不确定 Scala 类型别名究竟有多“弱”……由于路径依赖类型,它们比 Haskell 的别名强一点,但比类声明弱。也许其他人可以进一步解释。

那么,如果 Scala 只是忽略它们并重写类型,为什么它允许您在其中放置差异注释呢?它适用于类型成员。这样你就可以说

trait A { type F[+T] }

并要求实现符合+T差异,以便您允许

trait B extends A { type F[+T] = List[T] }

但不是

trait C extends A { type F[T] = Function[T,T] }

或者,就像 Scala Language Spec S4.3 中的这句话一样.

A type constructor declaration imposes additional restrictions on the concrete types for which t may stand. Besides the bounds L and U , the type parameter clause may impose higher-order bounds and variances, as governed by the conformance of type constructors (§3.5.2).

关于scala - 类型别名中的方差注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10523199/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com