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
A method with _implicit parameters_ can be applied to arguments just like a normal method. In this case the implicit label has no effect. However, if such a method misses arguments for its implicit parameters, such arguments will be automatically provided.
15
-
16
-
The actual arguments that are eligible to be passed to an implicit parameter fall into two categories:
17
-
18
-
* First, eligible are all identifiers x that can be accessed at the point of the method call without a prefix and that denote an implicit definition or an implicit parameter.
19
-
* Second, eligible are also all members of companion modules of the implicit parameter's type that are labeled implicit.
20
-
21
-
In the following example we define a method `sum` which computes the sum of a list of elements using the monoid's `add` and `unit` operations. Please note that implicit values can not be top-level, they have to be members of a template.
22
-
14
+
Implicit parameters allow for the caller to omit an argument if an implicit one is in scope. Use the `implicit` keyword to make a value, object, or expression implicit. You also use it to make the parameter list implicit.
23
15
```tut
24
-
/** This example uses a structure from abstract algebra to show how implicit parameters work. A semigroup is an algebraic structure on a set A with an (associative) operation, called add here, that combines a pair of A's and returns another A. */
25
-
abstract class SemiGroup[A] {
26
-
def add(x: A, y: A): A
27
-
}
28
-
/** A monoid is a semigroup with a distinguished element of A, called unit, that when combined with any other element of A returns that other element again. */
29
-
abstract class Monoid[A] extends SemiGroup[A] {
30
-
def unit: A
31
-
}
32
-
object ImplicitTest extends App {
33
-
/** To show how implicit parameters work, we first define monoids for strings and integers. The implicit keyword indicates that the corresponding object can be used implicitly, within this scope, as a parameter of a function marked implicit. */
def add(x: String, y: String): String = x concat y
36
-
def unit: String = ""
37
-
}
38
-
implicit object IntMonoid extends Monoid[Int] {
39
-
def add(x: Int, y: Int): Int = x + y
40
-
def unit: Int = 0
41
-
}
42
-
/** This method takes a List[A] returns an A which represent the combined value of applying the monoid operation successively across the whole list. Making the parameter m implicit here means we only have to provide the xs parameter at the call site, since if we have a List[A] we know what type A actually is and therefore what type Monoid[A] is needed. We can then implicitly find whichever val or object in the current scope also has that type and use that without needing to specify it explicitly. */
43
-
def sum[A](xs: List[A])(implicit m: Monoid[A]): A =
44
-
if (xs.isEmpty) m.unit
45
-
else m.add(xs.head, sum(xs.tail))
46
-
47
-
/** Here we call sum twice, with only one parameter each time. Since the second parameter of sum, m, is implicit its value is looked up in the current scope, based on the type of monoid required in each case, meaning both expressions can be fully evaluated. */
printGreeting("Fred")(new Greeting("Good day")) // Good day, Fred
55
27
```
56
-
6
57
-
abc
58
-
```
28
+
The `implicit val standardGreeting` is a value that can be supplied as an argument to an implicit parameter automatically. In the method `printGreeting`, the parameter `greeting` is implicit. This means that the caller can either supply an argument normally or skip it. With `greet("Franchesca")`, the compiler doesn't see a greeting but it notices that `greeting` is an implicit parameter so it searches the current scope for an implicit `Greeting` and finds `standardGreeting`.
29
+
30
+
This becomes useful when you have a lot of similar arguments to function calls throughout your program. However, implicits can make code more difficult to understand because it's not always obvious where they're defined if you import them from another module with a wildcard (e.g. `import MyPredef._`).
0 commit comments