3
3
Call-by-name implicit parameters can be used to avoid a divergent implicit expansion.
4
4
5
5
``` scala
6
+ trait Serializable [T ] {
7
+ def write (x : T ): Unit
8
+ }
9
+
10
+ implicit def serializeInt : Serializable [Int ] = ???
11
+
6
12
implicit def serializeOption [T ](implicit ev : => Serializable [T ]): Serializable [Option [T ]] =
7
13
new Serializable [Option [T ]] {
8
- def write (x : Option [T ], out : DataOutputStream ) = t match {
14
+ def write (xo : Option [T ]) = xo match {
9
15
case Some (x) => ev.write(x)
10
16
case None =>
11
17
}
12
18
}
13
19
14
- val s = serializeOption[Option [Int ]]
15
- s.write(Some (33 ))
16
- s.write(None )
20
+ val s = implicitly[Serializable [Option [Int ]]]
21
+
22
+ s.write(Some (33 ))
23
+ s.write(None )
17
24
```
18
25
As is the case for a normal by-name parameter, the argument for the implicit parameter ` ev `
19
26
is evaluated on demand. In the example above, if the option value ` x ` is ` None ` , it is
20
27
not evaluated at all.
21
28
22
29
The synthesized argument for an implicit parameter is backed by a lazy
23
- val, which means that the parameter is evaluated at most once. The
24
- lazy val is also available as a value for implicit search, which can
25
- be useful to avoid an otherwise diverging expansion.
30
+ val if this is necessary to prevent an otherwise diverging expansion.
26
31
27
- The precise steps for constructing an implicit argument for a by-name parameter of type ` => T ` are:
32
+ The precise steps for constructing an implicit argument for a by-name parameter of type ` => T ` are as follows.
28
33
29
34
1 . Create a new implicit value with a fresh name _ lv_ , which has the signature of the following definition:
30
35
@@ -40,3 +45,10 @@ The precise steps for constructing an implicit argument for a by-name parameter
40
45
41
46
Otherwise, return ` E ` unchanged.
42
47
48
+ In the example above, the definition of ` s ` would be expanded as follows.
49
+
50
+ val s = implicitly[ Test.Serializable[ Option[ Int]]] (
51
+ serializeOption[ Int] ( serializeInt )
52
+ )
53
+
54
+ No lazy val was generated because the synthesized argument is not recursive.
0 commit comments