Context Functions - More Details
Syntax
Type ::= ... | FunArgTypes ‘?=>’ Type Expr ::= ... | FunParams ‘?=>’ Expr
Context function types associate to the right, e.g.
S ?=> T ?=> U
is the same as S ?=> (T ?=> U)
.
Implementation
Context function types are shorthands for class types that define apply
methods with context parameters. Specifically, the N
-ary function type
T1, ..., TN => R
is a shorthand for the class type
ContextFunctionN[T1 , ... , TN, R]
. Such class types are assumed to have the following definitions, for any value of N >= 1
:
package scala
trait ContextFunctionN[-T1 , ... , -TN, +R] {
def apply(using x1: T1 , ... , xN: TN): R
}
Context function types erase to normal function types, so these classes are generated on the fly for typechecking, but not realized in actual code.
Context function literals (using x1: T1, ..., xn: Tn) => e
map
context parameters xi
of types Ti
to the result of evaluating the expression e
.
The scope of each context parameter xi
is e
. The parameters must have pairwise distinct names.
If the expected type of the context function literal is of the form
scala.ContextFunctionN[S1, ..., Sn, R]
, the expected type of e
is R
and
the type Ti
of any of the parameters xi
can be omitted, in which case Ti = Si
is assumed. If the expected type of the context function literal is
some other type, all context parameter types must be explicitly given, and the expected type of e
is undefined.
The type of the context function literal is scala.ContextFunctionN[S1, ...,Sn, T]
, where T
is the widened
type of e
. T
must be equivalent to a type which does not refer to any of
the context parameters xi
.
The context function literal is evaluated as the instance creation expression
new scala.ContextFunctionN[T1, ..., Tn, T] {
def apply(using x1: T1, ..., xn: Tn): T = e
}
A context parameter may also be a wildcard represented by an underscore _
. In that case, a fresh name for the parameter is chosen arbitrarily.
Note: The closing paragraph of the Anonymous Functions section of Scala 2.12 is subsumed by context function types and should be removed.
Context function literals (using x1: T1, ..., xn: Tn) => e
are
automatically created for any expression e
whose expected type is
scala.ContextFunctionN[T1, ..., Tn, R]
, unless e
is
itself a context function literal. This is analogous to the automatic
insertion of scala.Function0
around expressions in by-name argument position.
Context function types generalize to N > 22
in the same way that function types do, see the corresponding
documentation.
Examples
See the section on Expressiveness from Simplicitly: foundations and applications of implicit function types.
Type Checking
After desugaring no additional typing rules are required for context function types.