上下文函数 - 更多细节
语法
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]
,其中 T
是 e
的扩展类型。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 中关于表达能力的部分。
类型检查
在反糖化后,不需要为上下文函数类型添加额外的类型规则。