Skip to content

Make code readable in the web version #878

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 22 additions & 5 deletions _tour/implicit-parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,24 @@ The actual arguments that are eligible to be passed to an implicit parameter fal
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.

```tut
/** 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. */
/** 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. */
abstract class SemiGroup[A] {
def add(x: A, y: A): A
}
/** 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. */
/** 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. */
abstract class Monoid[A] extends SemiGroup[A] {
def unit: A
}
object ImplicitTest extends App {
/** 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. */
/** 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. */
implicit object StringMonoid extends Monoid[String] {
def add(x: String, y: String): String = x concat y
def unit: String = ""
Expand All @@ -41,12 +49,21 @@ object ImplicitTest extends App {
def add(x: Int, y: Int): Int = x + y
def unit: Int = 0
}
/** 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. */
/** 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. */
def sum[A](xs: List[A])(implicit m: Monoid[A]): A =
if (xs.isEmpty) m.unit
else m.add(xs.head, sum(xs.tail))

/** 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. */
/** 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. */
println(sum(List(1, 2, 3))) // uses IntMonoid implicitly
println(sum(List("a", "b", "c"))) // uses StringMonoid implicitly
}
Expand Down