You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
inferable parameters `xi` of types `Ti` to a result given by expression `e`.
35
+
The scope of each implicit parameter `xi` is `e`. The parameters must have pairwise distinct names.
38
36
39
-
If the expected type of the anonymous implicit function is of the form
37
+
If the expected type of the query literal is of the form
40
38
`scala.ImplicitFunctionN[S1, ..., Sn, R]`, the expected type of `e` is `R` and
41
39
the type `Ti` of any of the parameters `xi` can be omitted, in which case `Ti
42
-
= Si` is assumed. If the expected type of the anonymous implicit function is
43
-
some other type, all implicit parameter types must be explicitly given, and
44
-
the expected type of `e` is undefined. The type of the anonymous implicit
45
-
function is `scala.ImplicitFunctionN[S1, ...,Sn, T]`, where `T` is the widened
40
+
= Si` is assumed. If the expected type of the query literal is
41
+
some other type, all inferable parameter types must be explicitly given, and the expected type of `e` is undefined. The type of the query literal is `scala.ImplicitFunctionN[S1, ...,Sn, T]`, where `T` is the widened
46
42
type of `e`. `T` must be equivalent to a type which does not refer to any of
47
-
the implicit parameters `xi`.
43
+
the inferable parameters `xi`.
48
44
49
-
The anonymous implicit function is evaluated as the instance creation
45
+
The query literal is evaluated as the instance creation
50
46
expression:
51
47
52
48
new scala.ImplicitFunctionN[T1, ..., Tn, T] {
53
-
def apply with (x1: T1, ..., xn: Tn): T = e
49
+
def apply given (x1: T1, ..., xn: Tn): T = e
54
50
}
55
51
56
-
In the case of a single untyped implicit parameter, `given (x) => e` can be
52
+
In the case of a single untyped parameter, `given (x) => e` can be
57
53
abbreviated to `given x => e`.
58
54
59
-
A implicit parameter may also be a wildcard represented by an underscore `_`. In
55
+
An inferable parameter may also be a wildcard represented by an underscore `_`. In
60
56
that case, a fresh name for the parameter is chosen arbitrarily.
61
57
62
58
Note: The closing paragraph of the [Anonymous Functions section](https://www
Copy file name to clipboardExpand all lines: docs/docs/reference/instances/implicit-function-types.md
+22-20Lines changed: 22 additions & 20 deletions
Original file line number
Diff line number
Diff line change
@@ -1,14 +1,15 @@
1
1
---
2
2
layout: doc-page
3
-
title: "Implicit Function Types and Values"
3
+
title: "First Class Queries"
4
4
---
5
5
6
-
An implicit function type describes functions with inferred parameters. Example:
6
+
In the context of inference, _queries_ are functions with inferable parameters.
7
+
_Query types_ are the types of first-class queries. Example:
7
8
```scala
8
9
typeContextual[T] =givenContext=>T
9
10
```
10
-
A value of implicit function type is applied to inferred arguments, in
11
-
the same way a method with inferred parameters is applied. For instance:
11
+
A value of query type is applied to inferred arguments, in
12
+
the same way a method with inferable parameters is applied. For instance:
12
13
```scala
13
14
inferred ctx forContext= ...
14
15
@@ -17,18 +18,20 @@ the same way a method with inferred parameters is applied. For instance:
17
18
f(2) givenctx// explicit argument
18
19
f(2) // argument is inferred
19
20
```
20
-
Conversely, if the expected type of an expression `E` is an implicit
21
-
function type `given (T_1, ..., T_n) => U` and `E` is not already an
22
-
implicit function value, `E` is converted to an inferred function value
23
-
by rewriting to
21
+
Conversely, if the expected type of an expression `E` is a query
22
+
type `given (T_1, ..., T_n) => U` and `E` is not already a
23
+
query literal, `E` is converted to a query literal by rewriting to
24
24
```scala
25
25
given (x_1: T1, ..., x_n: Tn) =>E
26
26
```
27
-
where the names `x_1`, ..., `x_n` are arbitrary. Inferred function values are written
28
-
with a `given` prefix. They differ from normal function values in two ways:
27
+
where the names `x_1`, ..., `x_n` are arbitrary. This expansion is performed
28
+
before the expression `E` is typechecked, which means that x_1`, ..., `x_n`
29
+
are available as inferred instances in `E`.
29
30
30
-
1. Their parameters are inferred parameters
31
-
2. Their types are implicit function types.
31
+
Like query types, query literals are written with a `given` prefix. They differ from normal function literals in two ways:
32
+
33
+
1. Their parameters are inferable.
34
+
2. Their types are query types.
32
35
33
36
For example, continuing with the previous definitions,
34
37
```scala
@@ -42,7 +45,7 @@ For example, continuing with the previous definitions,
42
45
```
43
46
### Example: Builder Pattern
44
47
45
-
Implicit function types have considerable expressive power. For
48
+
Query types have considerable expressive power. For
46
49
instance, here is how they can support the "builder pattern", where
47
50
the aim is to construct tables like this:
48
51
```scala
@@ -75,17 +78,17 @@ addition of elements via `add`:
75
78
caseclassCell(elem: String)
76
79
```
77
80
Then, the `table`, `row` and `cell` constructor methods can be defined
78
-
in terms of implicit function types to avoid the plumbing boilerplate
81
+
in terms of query types to avoid the plumbing boilerplate
79
82
that would otherwise be necessary.
80
83
```scala
81
84
deftable(init: givenTable=>Unit) = {
82
-
instance t ofTable
85
+
inferred t forTable
83
86
init
84
87
t
85
88
}
86
89
87
90
defrow(init: givenRow=>Unit) given (t: Table) = {
88
-
instance r ofRow
91
+
inferred r forRow
89
92
init
90
93
t.add(r)
91
94
}
@@ -108,7 +111,7 @@ With that setup, the table construction code above compiles and expands to:
108
111
```
109
112
### Example: Postconditions
110
113
111
-
As a larger example, here is a way to define constructs for checking arbitrary postconditions using `ensuring` so that the checked result can be referred to simply by `result`. The example combines opaque aliases, implicit function types, and extensions to provide a zero-overhead abstraction.
114
+
As a larger example, here is a way to define constructs for checking arbitrary postconditions using `ensuring` so that the checked result can be referred to simply by `result`. The example combines opaque aliases, query types, and extension methods to provide a zero-overhead abstraction.
112
115
113
116
```scala
114
117
objectPostConditions {
@@ -133,10 +136,9 @@ object Test {
133
136
vals=List(1, 2, 3).sum.ensuring(result ==6)
134
137
}
135
138
```
136
-
**Explanations**: We use an implicit function type `given WrappedResult[T] => Boolean`
139
+
**Explanations**: We use a query type `given WrappedResult[T] => Boolean`
137
140
as the type of the condition of `ensuring`. An argument to `ensuring` such as
138
-
`(result == 6)` will therefore have an implicit value of type `WrappedResult[T]` in scope
139
-
to pass along to the `result` method. `WrappedResult` is a fresh type, to make sure that we do not get unwanted inferred instances in scope (this is good practice in all cases where inferred parameters are involved). Since `WrappedResult` is an opaque type alias, its values need not be boxed, and since `ensuring` is added as an extension method, its argument does not need boxing either. Hence, the implementation of `ensuring` is as about as efficient as the best possible code one could write by hand:
141
+
`(result == 6)` will therefore have an inferred instance of type `WrappedResult[T]` in scope to pass along to the `result` method. `WrappedResult` is a fresh type, to make sure that we do not get unwanted inferred instances in scope (this is good practice in all cases where inferred parameters are involved). Since `WrappedResult` is an opaque type alias, its values need not be boxed, and since `ensuring` is added as an extension method, its argument does not need boxing either. Hence, the implementation of `ensuring` is as about as efficient as the best possible code one could write by hand:
0 commit comments