diff options
author | Antoine Gourlay <antoine@gourlay.fr> | 2014-09-15 12:08:51 +0200 |
---|---|---|
committer | Antoine Gourlay <antoine@gourlay.fr> | 2014-09-17 13:40:09 +0200 |
commit | 3b0c71df60a41e13e47ec9ae8dbc606e1928aba8 (patch) | |
tree | 306897801df10e0318b454c67738156997e4b29d /spec/07-implicit-parameters-and-views.md | |
parent | bca19f35103c4ff1205e1c8054eb3f803217a18b (diff) | |
download | scala-3b0c71df60a41e13e47ec9ae8dbc606e1928aba8.tar.gz scala-3b0c71df60a41e13e47ec9ae8dbc606e1928aba8.tar.bz2 scala-3b0c71df60a41e13e47ec9ae8dbc606e1928aba8.zip |
spec: remove trailing whitespace everywhere
Diffstat (limited to 'spec/07-implicit-parameters-and-views.md')
-rw-r--r-- | spec/07-implicit-parameters-and-views.md | 47 |
1 files changed, 19 insertions, 28 deletions
diff --git a/spec/07-implicit-parameters-and-views.md b/spec/07-implicit-parameters-and-views.md index e07adc9e82..3a215e74fc 100644 --- a/spec/07-implicit-parameters-and-views.md +++ b/spec/07-implicit-parameters-and-views.md @@ -15,7 +15,7 @@ ParamClauses ::= {ParamClause} [nl] ‘(’ ‘implicit’ Params ‘)’ Template members and parameters labeled with an `implicit` modifier can be passed to [implicit parameters](#implicit-parameters) -and can be used as implicit conversions called [views](#views). +and can be used as implicit conversions called [views](#views). The `implicit` modifier is illegal for all type members, as well as for [top-level objects](09-top-level-definitions.html#packagings). @@ -41,7 +41,6 @@ object Monoids { } ``` - ## Implicit Parameters An implicit parameter list @@ -57,7 +56,7 @@ parameters, such arguments will be automatically provided. The actual arguments that are eligible to be passed to an implicit parameter of type $T$ fall into two categories. First, eligible are all identifiers $x$ that can be accessed at the point of the method -call without a prefix and that denote an +call without a prefix and that denote an [implicit definition](#the-implicit-modifier) or an implicit parameter. An eligible identifier may thus be a local name, or a member of an enclosing @@ -117,7 +116,6 @@ eligible object which matches the implicit formal parameter type `Monoid[Int]` is `intMonoid` so this object will be passed as implicit parameter. - This discussion also shows that implicit parameters are inferred after any type arguments are [inferred](06-expressions.html#local-type-inference). @@ -128,7 +126,7 @@ type of the list is also convertible to this type. ```scala implicit def list2ordered[A](x: List[A]) - (implicit elem2ordered: A => Ordered[A]): Ordered[List[A]] = + (implicit elem2ordered: A => Ordered[A]): Ordered[List[A]] = ... ``` @@ -145,8 +143,8 @@ define a `sort` method over ordered lists: def sort[A](xs: List[A])(implicit a2ordered: A => Ordered[A]) = ... ``` -We can apply `sort` to a list of lists of integers -`yss: List[List[Int]]` +We can apply `sort` to a list of lists of integers +`yss: List[List[Int]]` as follows: ```scala @@ -161,11 +159,11 @@ sort(yss)(xs: List[Int] => list2ordered[Int](xs)(int2ordered)) . The possibility of passing implicit arguments to implicit arguments raises the possibility of an infinite recursion. For instance, one -might try to define the following method, which injects _every_ type into the +might try to define the following method, which injects _every_ type into the `Ordered` class: ```scala -implicit def magic[A](x: A)(implicit a2ordered: A => Ordered[A]): Ordered[A] = +implicit def magic[A](x: A)(implicit a2ordered: A => Ordered[A]): Ordered[A] = a2ordered(x) ``` @@ -178,7 +176,7 @@ expansion: sort(arg)(x => magic(x)(x => magic(x)(x => ... ))) ``` -To prevent such infinite expansions, the compiler keeps track of +To prevent such infinite expansions, the compiler keeps track of a stack of “open implicit types” for which implicit arguments are currently being searched. Whenever an implicit argument for type $T$ is searched, the “core type” of $T$ is added to the stack. Here, the _core type_ @@ -190,7 +188,7 @@ the implicit argument either definitely fails or succeeds. Everytime a core type is added to the stack, it is checked that this type does not dominate any of the other types in the set. -Here, a core type $T$ _dominates_ a type $U$ if $T$ is +Here, a core type $T$ _dominates_ a type $U$ if $T$ is [equivalent](03-types.html#type-equivalence) to $U$, or if the top-level type constructors of $T$ and $U$ have a common element and $T$ is more complex than $U$. @@ -212,7 +210,6 @@ the type: - For any other singleton type, $\operatorname{complexity}(p.type) ~=~ 1 + \operatorname{complexity}(T)$, provided $p$ has type $T$; - For a compound type, `$\operatorname{complexity}(T_1$ with $\ldots$ with $T_n)$` $= \Sigma\operatorname{complexity}(T_i)$ - ###### Example When typing `sort(xs)` for some list `xs` of type `List[List[List[Int]]]`, the sequence of types for @@ -228,7 +225,6 @@ All types share the common type constructor `scala.Function1`, but the complexity of the each new type is lower than the complexity of the previous types. Hence, the code typechecks. - ###### Example Let `ys` be a list of some type which cannot be converted to `Ordered`. For instance: @@ -249,7 +245,6 @@ Throwable => Ordered[Throwable], Since the second type in the sequence is equal to the first, the compiler will issue an error signalling a divergent implicit expansion. - ## Views Implicit parameters and methods can also define implicit conversions @@ -266,7 +261,7 @@ Views are applied in three situations: $\mathit{pt}$. The search proceeds as in the case of implicit parameters, where the implicit scope is the one of `$T$ => $\mathit{pt}$`. If such a view is found, the expression $e$ is converted to - `$v$($e$)`. + `$v$($e$)`. 1. In a selection $e.m$ with $e$ of type $T$, if the selector $m$ does not denote an accessible member of $T$. In this case, a view $v$ is searched which is applicable to $e$ and whose result contains a member named @@ -275,13 +270,12 @@ Views are applied in three situations: selection $e.m$ is converted to `$v$($e$).$m$`. 1. In a selection $e.m(\mathit{args})$ with $e$ of type $T$, if the selector $m$ denotes some member(s) of $T$, but none of these members is applicable to the arguments - $\mathit{args}$. In this case a view $v$ is searched which is applicable to $e$ + $\mathit{args}$. In this case a view $v$ is searched which is applicable to $e$ and whose result contains a method $m$ which is applicable to $\mathit{args}$. The search proceeds as in the case of implicit parameters, where the implicit scope is the one of $T$. If such a view is found, the selection $e.m$ is converted to `$v$($e$).$m(\mathit{args})$`. - The implicit view, if it is found, can accept is argument $e$ as a call-by-value or as a call-by-name parameter. However, call-by-value implicits take precedence over call-by-name implicits. @@ -319,17 +313,16 @@ The first application of `list2ordered` converts the list occurrence is part of an implicit parameter passed to the `<=` method. - ## Context Bounds and View Bounds ```ebnf - TypeParam ::= (id | ‘_’) [TypeParamClause] [‘>:’ Type] [‘<:’ Type] + TypeParam ::= (id | ‘_’) [TypeParamClause] [‘>:’ Type] [‘<:’ Type] {‘<%’ Type} {‘:’ Type} ``` A type parameter $A$ of a method or non-trait class may have one or more view bounds `$A$ <% $T$`. In this case the type parameter may be -instantiated to any type $S$ which is convertible by application of a +instantiated to any type $S$ which is convertible by application of a view to the bound $T$. A type parameter $A$ of a method or non-trait class may also have one @@ -375,10 +368,9 @@ def <= [B >: A <% Ordered[B]](that: B): Boolean ## Manifests - Manifests are type descriptors that can be automatically generated by the Scala compiler as arguments to implicit parameters. The Scala -standard library contains a hierarchy of four manifest classes, +standard library contains a hierarchy of four manifest classes, with `OptManifest` at the top. Their signatures follow the outline below. @@ -399,7 +391,7 @@ argument is selected. Otherwise, let $\mathit{Mobj}$ be the companion object `scala.reflect.Manifest` if $M$ is trait `Manifest`, or be the companion object `scala.reflect.ClassManifest` otherwise. Let $M'$ be the trait -`Manifest` if $M$ is trait `Manifest`, or be the trait `OptManifest` otherwise. +`Manifest` if $M$ is trait `Manifest`, or be the trait `OptManifest` otherwise. Then the following rules apply. 1. If $T$ is a value class or one of the classes `Any`, `AnyVal`, `Object`, @@ -416,26 +408,25 @@ Then the following rules apply. where $m_0$ is the manifest determined for $M'[S]$ and $ms$ are the manifests determined for $M'[U_1], \ldots, M'[U_n]$. 1. If $T$ is some other class type with type arguments $U_1 , \ldots , U_n$, - a manifest is generated + a manifest is generated with the invocation `$\mathit{Mobj}$.classType[T](classOf[T], $ms$)` where $ms$ are the manifests determined for $M'[U_1] , \ldots , M'[U_n]$. 1. If $T$ is a singleton type `$p$.type`, a manifest is generated with - the invocation `$\mathit{Mobj}$.singleType[T]($p$)` + the invocation `$\mathit{Mobj}$.singleType[T]($p$)` 1. If $T$ is a refined type $T' \{ R \}$, a manifest is generated for $T'$. (That is, refinements are never reflected in manifests). 1. If $T$ is an intersection type `$T_1$ with $, \ldots ,$ with $T_n$` where $n > 1$, the result depends on whether a full manifest is - to be determined or not. + to be determined or not. If $M$ is trait `Manifest`, then a manifest is generated with the invocation `Manifest.intersectionType[T]($ms$)` where $ms$ are the manifests determined for $M[T_1] , \ldots , M[T_n]$. - Otherwise, if $M$ is trait `ClassManifest`, + Otherwise, if $M$ is trait `ClassManifest`, then a manifest is generated for the [intersection dominator](03-types.html#type-erasure) of the types $T_1 , \ldots , T_n$. 1. If $T$ is some other type, then if $M$ is trait `OptManifest`, a manifest is generated from the designator `scala.reflect.NoManifest`. If $M$ is a type different from `OptManifest`, a static error results. - |