在 GitHub 上编辑此页面

上下文函数 - 更多细节

语法

Type              ::=  ...
                    |  FunArgTypes ‘?=>’ Type
Expr              ::=  ...
                    |  FunParams ‘?=>’ Expr

上下文函数类型向右关联,例如 S ?=> T ?=> U 等同于 S ?=> (T ?=> U)

实现

上下文函数类型是定义了带上下文参数的 apply 方法的类类型的简写。具体来说,N 元函数类型

T1, ..., TN ?=> R 是类类型 ContextFunctionN[T1, ..., TN, R] 的简写。对于任何 N >= 1 的值,这些类类型都假定具有以下定义

package scala
trait ContextFunctionN[-T1, ..., -TN, +R]:
  def apply(using x1: T1, ..., xN: TN): R

上下文函数类型擦除为普通函数类型,因此这些类是在类型检查时动态生成的,但在实际代码中不会实现。

上下文函数字面量 (x1: T1, ..., xn: Tn) ?=> e 将类型为 Ti 的上下文参数 xi 映射到表达式 e 的求值结果。每个上下文参数 xi 的作用域是 e。参数必须具有成对不同的名称。

如果上下文函数字面量的预期类型为 scala.ContextFunctionN[S1, ..., Sn, R] 形式,则 e 的预期类型为 R,并且任何参数 xi 的类型 Ti 可以省略,在这种情况下,假设 Ti = Si。如果上下文函数字面量的预期类型为其他类型,则必须显式给出所有上下文参数类型,并且 e 的预期类型未定义。上下文函数字面量的类型为 scala.ContextFunctionN[S1, ...,Sn, T],其中 Te 的扩展类型。T 必须等效于不引用任何上下文参数 xi 的类型。

上下文函数字面量被评估为实例创建表达式

new scala.ContextFunctionN[T1, ..., Tn, T]:
  def apply(using x1: T1, ..., xn: Tn): T = e

上下文参数也可以是下划线 _ 表示的通配符。在这种情况下,将任意选择参数的新名称。

注意:Scala 2.13 的 匿名函数部分 的结尾段落被上下文函数类型取代,应该删除。

对于任何预期类型为 scala.ContextFunctionN[T1, ..., Tn, R] 的表达式 e,都会自动创建上下文函数字面量 (x1: T1, ..., xn: Tn) ?=> e,除非 e 本身是上下文函数字面量。这类似于在按名称参数位置自动插入 scala.Function0

上下文函数类型以与函数类型相同的方式推广到 N > 22,请参阅 相应的文档

示例

请参阅 Simplicitly: foundations and applications of implicit function types 中关于表达能力的部分。

类型检查

在反糖化后,不需要为上下文函数类型添加额外的类型规则。