|
| 1 | +--- |
| 2 | +layout: doc-page |
| 3 | +title: "Implicit Function Types - More Details" |
| 4 | +--- |
| 5 | + |
| 6 | +Initial implementation in (#1775)[https://github.com/lampepfl/dotty/pull/1775]. |
| 7 | + |
| 8 | +## Syntax |
| 9 | + |
| 10 | + Type ::= [`implicit'] FunArgTypes `=>' Type |
| 11 | + | HkTypeParamClause `=>' Type |
| 12 | + | InfixType |
| 13 | + Expr ::= [`implicit'] FunParams `=>' Expr |
| 14 | + BlockResult ::= [`implicit'] FunParams `=>' Block |
| 15 | + | Expr1 |
| 16 | + |
| 17 | +Implicit function types associate to the right, e.g. |
| 18 | +`implicit S ⇒ implicit T ⇒ U` is the same as `implicit S ⇒ (implicit T ⇒ U)`. |
| 19 | + |
| 20 | +## Implementation |
| 21 | + |
| 22 | +Implicit function types are shorthands for class types that define `apply` |
| 23 | +methods with implicit parameters. Specifically, the `N`-ary function type |
| 24 | +`implicit T1, ..., TN ⇒ R` is a shorthand for the class type |
| 25 | +`ImplicitFunctionN[T1 , ... , TN, R]`. Such class types are defined in the |
| 26 | +Scala library for `N` between 1 and 22 as follows. |
| 27 | + |
| 28 | + package scala |
| 29 | + trait ImplicitFunctionN[-T1 , ... , -TN, +R] { |
| 30 | + def apply(implicit x1: T1 , ... , xN: TN): R |
| 31 | + } |
| 32 | + |
| 33 | +Anonymous implicit functions `implicit (x1: T1, ..., xn: Tn) => e` map |
| 34 | +implicit parameters `xi` of types `Ti` to a result given by expression `e`. |
| 35 | +The scope of each implicit parameter `xi` is `e`. Implicit parameters must |
| 36 | +have pairwise distinct names. |
| 37 | + |
| 38 | +If the expected type of the anonymous implicit function is of the form |
| 39 | +`scala.ImplicitFunctionN[S1, ..., Sn, R]`, the expected type of `e` is `R` and |
| 40 | +the type `Ti` of any of the parameters `xi` can be omitted, in which case `Ti |
| 41 | += Si` is assumed. If the expected type of the anonymous implicit function is |
| 42 | +some other type, all implicit parameter types must be explicitly given, and |
| 43 | +the expected type of `e` is undefined. The type of the anonymous implicit |
| 44 | +function is `scala.ImplicitFunctionN[S1, ...,Sn, T]`, where `T` is the widened |
| 45 | +type of `e`. `T` must be equivalent to a type which does not refer to any of |
| 46 | +the implicit parameters `xi`. |
| 47 | + |
| 48 | +The anonymous implicit function is evaluated as the instance creation |
| 49 | +expression: |
| 50 | + |
| 51 | + new scala.ImplicitFunctionN[T1, ..., Tn, T] { |
| 52 | + def apply(implicit x1: T1, ..., xn: Tn): T = e |
| 53 | + } |
| 54 | + |
| 55 | +In the case of a single untyped implicit parameter, `implicit (x) => e` can be |
| 56 | +abbreviated to `implicit x => e`. If an anonymous implicit function `implicit |
| 57 | +(x: T) => e` with a single typed parameter appears as the result expression of |
| 58 | +a block, it can be abbreviated to `implicit x: T => e` |
| 59 | + |
| 60 | +A implicit parameter may also be a wildcard represented by an underscore `_`. In |
| 61 | +that case, a fresh name for the parameter is chosen arbitrarily. |
| 62 | + |
| 63 | +Note: The closing paragraph of the [Anonymous Functions section](https://www |
| 64 | +.scala-lang.org/files/archive/spec/2.12/06-expressions.html#anonymous- |
| 65 | +functions) of the Scala 2.12 is subsumed by implicit function types and should |
| 66 | +be removed. |
| 67 | + |
| 68 | +Anonymous implicit functions `implicit (x1: T1, ..., xn: Tn) => e` are |
| 69 | +automatically inserted around any expression `e` whose expected type is |
| 70 | +`scala.ImplicitFunctionN[T1, ..., Tn, R]`. This is analogous to the automatic |
| 71 | +insertion of `scala.Function0` around expression in by-name argument position. |
| 72 | + |
| 73 | +Implicit functions generalize to `N > 22` in the same way that functions do, |
| 74 | +see [the corresponding |
| 75 | +documentation](https://dotty.epfl.ch/docs/reference/dropped/limit22.html). |
| 76 | + |
| 77 | +## Examples |
| 78 | + |
| 79 | +See the section on Expressiveness from [Simplicitly: foundations and |
| 80 | +applications of implicit function |
| 81 | +types](https://dl.acm.org/citation.cfm?id=3158130). I've extracted it in [this |
| 82 | +Gist](https://gist.github.com/OlivierBlanvillain/234d3927fe9e9c6fba074b53a7bd9 |
| 83 | +592), it might easier to access than the pdf. |
| 84 | + |
| 85 | +### Type Checking |
| 86 | + |
| 87 | +After desugaring no additional typing rules are required for implicit function |
| 88 | +types. |
0 commit comments