This code compiles and does exactly what one expects
class MyList[T](list: T)(implicit o: Ordering[T])
However this does not:
class MyList2[T](list: T) {
val o = implicitly[Ordering[T]]
}
And I can't see why. In the first example when the class is being constructed the compiler will find the Ordering implicit because it will know the concrete type T. But in the second case it should also find the implicit since T will already be a concrete type.
In the first example when the class is being constructed the compiler
will find the Ordering implicit because it will know the concrete type
T.
In the first example, one needs to have an implicit Ordering[T] in scope for the compiler to find it. The compiler by itself doesn't "make up" implicits. Since you've directly required one to be available via the second parameter list, if such an implicit exists, it will be passed down to the class constructor.
But in the second case it should also find the implicit since T will
already be a concrete type.
The fact that T is a concrete type at compile time doesn't help the compiler find an implicit for it. When we say T is a concrete type, you must remember that at the call-site, T is simply a generic type parameter, nothing more. If you don't help the compiler, it can't give the guarantee of having an implicit in scope. You need to have the method supply an implicit, this can be done via a Context Bound:
class MyList2[T: Ordering](list: T)
Which requires the existence, at compile time, of an ordering for type T. Semantically, this is equivalent to your second parameter list.
You must always tell the compiler that an implicit should be provided for your type. That is, you must always put implicit o: Ordering[T]. What implicitly does is that it allows you to access the implicit in case you haven't named it. Note that you can use syntax sugar (called "context bound") for the implicit parameter, in which case implicitly becomes neccessary:
class MyList2[T : Ordering](list: T) {
val o = implicitly[Ordering[T]]
}
Type [T : Ordering] is a shorthand for "some type T for which an implicit Ordering[T] exists in scope". It's the same as writing:
class MyList2[T](list: T)(implicit o: Ordering[T]) {
}
but in that case implicitly is not needed since you can access your implicit parameter by its identifier o.
But in the second case it should also find the implicit since T will already be a concrete type.
Scala (and Java) generics don't work like C++ templates. The compiler isn't going to see MyList2[Int] elsewhere, generate
class MyList2_Int(list: Int) {
val o = implicitly[Ordering[Int]]
}
and typecheck that definition. It is MyList2 itself which gets typechecked, with no concrete T.
For the second to work, you need to specify that there is an Ordering for type T using a context bound:
class MyList2[T : Ordering](list: T) {
val o = implicitly[Ordering[T]]
}
Related
I am experimenting with a set of custom container functions and took inspiration from Scala's collections library with regard to the CanBuildFrom[-From, -Elem, -To] implicit parameter.
In Scala's collections, CanBuildFrom enables parametrization of the return type of functions like map. Internally the CanBuildFrom parameter is used like a factory: map applies it's first order function on it's input elements, feeds the result of each application into the CanBuildFrom parameter, and finally calls CanBuildFrom's result method which builds the final result of the map call.
In my understanding the -From type parameter of CanBuildFrom[-From, -Elem, -To] is only used in apply(from: From): Builder[Elem, To] which creates a Builder preinitialized with some elements. In my custom container functions I don't have that use case, so I created my own CanBuildFrom variant Factory[-Elem, +Target].
Now I can have a trait Mappable
trait Factory[-Elem, +Target] {
def apply(elems: Traversable[Elem]): Target
def apply(elem: Elem): Target = apply(Traversable(elem))
}
trait Mappable[A, Repr] {
def traversable: Traversable[A]
def map[B, That](f: A => B)(implicit factory: Factory[B, That]): That =
factory(traversable.map(f))
}
and an implementation Container
object Container {
implicit def elementFactory[A] = new Factory[A, Container[A]] {
def apply(elems: Traversable[A]) = new Container(elems.toSeq)
}
}
class Container[A](val elements: Seq[A]) extends Mappable[A, Container[A]] {
def traversable = elements
}
Unfortunately though, a call to map
object TestApp extends App {
val c = new Container(Seq(1, 2, 3, 4, 5))
val mapped = c.map { x => 2 * x }
}
yields an error message not enough arguments for method map: (implicit factory: tests.Factory[Int,That])That. Unspecified value parameter factory . The error goes away when I add an explicit import import Container._ or when I explicitly specify the expected return type val mapped: Container[Int] = c.map { x => 2 * x }
All of these "workarounds" become unnecessary when I add an unused third type parameter to Factory
trait Factory[-Source, -Elem, +Target] {
def apply(elems: Traversable[Elem]): Target
def apply(elem: Elem): Target = apply(Traversable(elem))
}
trait Mappable[A, Repr] {
def traversable: Traversable[A]
def map[B, That](f: A => B)(implicit factory: Factory[Repr, B, That]): That =
factory(traversable.map(f))
}
and change the implicit definition in Container
object Container {
implicit def elementFactory[A, B] = new Factory[Container[A], B, Container[B]] {
def apply(elems: Traversable[A]) = new Container(elems.toSeq)
}
}
So finally my question: Why is the seemingly unused -Source type parameter necessary to resolve the implicit?
And as an additional meta question: How do you solve these kinds of problems if you don't have a working implementation (the collection library) as a template?
Clarification
It might be helpful to explain why I thought the implicit resolution should work without the additional -Source type parameter.
According to this doc entry on implicit resolution, implicits are looked up in companion objects of types. The author does not provide an example for implicit parameters from companion objects (he only explains implicit conversion) but I think what this means is that a call to Container[A]#map should make all implicits from object Container available as implicit parameters, including my elementFactory. This assumption is supported by the fact that it is enough to provide the target type (no additional explicit imports!!) to get the implicit resolved.
The extra type parameter enables this behavior according to the specification of implicit resolution. Here is a summary from the FAQ answer to where do implicits come from (relevant parts bolded):
First look in current scope:
Implicits defined in current scope
Explicit imports
wildcard imports
Now look at associated types in:
Companion objects of a type (1)
Implicit scope of an argument’s type (2)
Implicit scope of type arguments (3)
Outer objects for nested types
Other dimensions
When you call map on a Mappable, you get the implicits from the implicit scope of its arguments, by (2). Since its argument is Factory in this case, that means that you also get the implicits from the implicit scope of all of type arguments of Factory, by (3). Next is the key: only when you add Source as a type parameter to Factory do you get all the implicits in the implicit scope of Container. Since the implicit scope of Container includes the implicits defined in its companion object (by (1)), this brings the desired implicit into scope without the imports you were using.
That's the syntactic reason, but there is a good semantic reason for this to be the desired behavior – unless the type is specified, the compiler would have no way of resolving the correct implicit when there may be conflicts. For example, if choosing between builder for a String or List[Char], the compiler needs to pick the correct one to enable "myFoo".map(_.toUpperCase) returning a String. If every implicit conversion were brought into scope all the time, this would be difficult or impossible. The above rules are meant to encompass an ordered list of what could possibly be relevant to the current scope in order to prevent this problem.
You can read more about implicits and implicit scope in the specification or in this great answer.
Here's why your other two solutions work: When you explicitly specify the return type of the call to map (in the version without the the Source parameter), then type inference comes into play, and the compiler can deduce that the parameter of interest That is Container, and therefore the implicit scope of Container comes into scope, including its companion object implicits. When you use an explicit import, then the desired implicit is in scope, trivially.
As for you meta-question, you can always click through the source code (or just checkout the repo), build minimal examples (like you have), and ask questions here. Using the REPL helps a lot to dealing with small examples like this.
The spec has a dedicated section on implicit parameter resolution. According to that section there are two sources for arguments to implicit parameters.
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. An eligible identifier may thus
be a local name, or a member of an enclosing template, or it may be
have been made accessible without a prefix through an import clause.
So every name which is available without qualification and which is marked with the implicit keyword can be used as implicit parameter.
second eligible are also all implicit members of some object that
belongs to the implicit scope of the implicit parameter's type, T.
The implicit scope of a type T consists of all companion modules of
classes that are associated with the implicit parameter's type. Here,
we say a class C is associated with a type T if it is a base class of
some part of T.
Implicits defined in companion objects (a.k.a companion modules) of all parts of the types of an implicit parameter list are also available as parameter. So in the original example
def map[B, That](f: A => B)(implicit factory: Factory[Repr, B, That]): That
we will get implicits defined in the companion objects of Factory, Repr, B, and That. As Ben Reich has pointed out in his answer, this explains why the Repr type parameter is necessary to find the implicit parameter.
Here is why it works with the explicitly defined return type
val mapped: Container[Int] = c.map { x => 2 * x }
With the explicit return type definition, type inference selects Container[Int] for the That parameter in Factory[Repr, B, That]. Therefore, implicits defined in Container are then available as well.
I'm not sure if I've got the terminology down right in the title, but what's the difference between this:
class Container[A <% Int] { def addIt(x: A) = 123 + x }
and this:
class Container[A](value: A) { def addIt(implicit evidence: A =:= Int) = 123 + value }
I suppose the question is why would I use one form of type bound over another? Is it simply a matter of being able to apply a type bound at different parts of the code (eg in the parameter list vs the body)?
Also, the documents say that methods may ask for "evidence" for a type rather then using other objects for type checking then provide the second code snippet. What kind of evidence are they referring to?
Note: this is regarding this article on advanced types.
View bounds are for when you want use a type that is viewable as another type. In your example, you want A to be viewable as Int. And what that means is we want any implicit conversion in scope from A => Int.
ie. it is the same as:
class Container(implicit evidence: A => Int) { def addIt(x: A) = 123 + x }
They are also deprecated. That should be reason enough to avoid them.
Type bounds is not the correct term for your second example. They are for strictly bounding the types of a parameter from above or below. A type bound would look like this:
class Container[A <: Int] { def addIt(x: A) = 123 + x }
In this example A must be strictly bounded above by Int. Implicit conversions cannot apply.
I'm not sure if there's really a name for your second example, but it differs from view bounds in that it requires an instance of the type class =:= seen here. It is similar to view bounds in that =:= witnesses that A is the same as Int, and therefore allows A to be converted explicitly to Int. However, it requires an instance of the type class =:=[A, Int] to exist, and not just any implicit conversion from A => Int.
Your two examples are kind of fundamentally different though. The first requires the view bound on the class itself, where the second requires the type evidence on the method. That is, the first example does not allow instances of Container[String] to exist at all (without an implicit conversion available), but the second one does. The second example happily allows you to construct a Container[String], but will not let you use the addIt method, unless you have evidence that String =:= Int.
By evidence we mean either an implicit conversion to the type we're interested in (A => Int), or an instance of the type class =:= that witnesses the equality. For types that are actually the same, we have those automatically generated in Predef (earlier link).
I declared two utility methods as implicit
class MyClass { ... }
object MyClass {
implicit def finish: MyClass[Any,Nothing,Unit] = finish(());
implicit def finish[R](result: R): MyClass[Any,Nothing,R] = ...
}
and I'm getting compiler warnings:
parameterized overloaded implicit methods are not visible as view bounds
What does this warning mean?
Here "parameterized" should really be "type parameterized".
Or in other wods, the warning says that because you have defined an implicit conversion that is both overloaded (there are other methods of the same name) and generic, then the method cannot actually be used as an implicit view, although it can be used to implicitly convert a mere value.
I'll try to illustrate the difference with an example:
class MyClass
object MyClass {
implicit def finish: MyClass = null
implicit def finish[R](result: R): MyClass = null
}
val a: Int = 123
val b: MyClass = a // Compiles fine: implicit conversion properly applied
def foo[R<%MyClass]( r: R ) {}
foo( 123 ) // Error: No implicit view available from Int => Test.MyClass
In the above code snippet, a (of type Int) is implicitly converted to MyClass, so the implicit conversion works as expected.
However, the interesting part is with the foo method. It is declared with a view bound to MyClass. In other words, you should be able to pass to foo any value that is implicitly convertible to MyClass. But here it fails to compile. This is this error that the compiler was warning you about.
And sure enough, if you comment out the first overload of finish (the one that does not take a type parameter), or rename a version so that they are not overloads (say you rename one of them to finish2), then the compile error goes away.
If you are wondering what is so different between the first case (direct implicit conversion) and the second one (call to method with a view bound) that would allow one to compile fine but not the other, the key point is that a view bound requires to pass a an implicit function value.
Indeed,
def foo[R<%MyClass]( r: R )
is the same as
def foo[R]( r: R )( implicit conv: R => MyClass)
So when calling foo, the compiler not only needs to find the appropriate implicit conversion, but also to promote the implicit conversion method (the second finish overload) to a function instance, and pass it implicitly to foo.
I believe that this is this promotion that the compiler (for some reason) does not know how to do in the case of type parameterized and overloaded methods.
This is pure speculation but I am pretty sure that this is just an implementation limitation: this would very much be doable, but it would introduce enough implementation problems that it was not deemed important enough (after all you can fix it by just renaming the implicit conversion method).
As a side note, the warning is not emitted (by default) in scala 2.10 (it was deemed too noisy, with the surge of type class usage in scala), but the real problem remains, and the call to foo still fails to compile.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What do <:<, <%<, and =:= mean in Scala 2.8, and where are they documented?
I'm curious since I saw them in Scala library code, but I found it quite hard to Google something about them since their names are not words.
These classes are used for implicit parameters that restrict the applicability of a method. Below is a description of each class. In general they are useful to restrain the a type parameter of an enclosing class within the context of a single method.
<:<[A,B] or A <:< B
The compiler can provide an implicit instance of this type only when A is a subtype of B. This is similar to A <: B in a type parameter list.
This can be useful when you want to put an additional constraint on a class type parameter in the context of a particular method. For example the class Foo below can be used with any type, but the method bar is only valid when T is a subtype of Number.
class Foo[T](x: T) {
// In general T could be any type
def bar(implicit ev: T <:< Number) = {
// This method can now only be used when T is a subtype of Number
// also, you can use ev to convert a T to number
ev(x).doubleValue
}
}
new Foo(123 : java.lang.Integer).bar // returns 123.0: Double
new Foo("123").bar // compile error: Cannot prove java.lang.String <:< java.lang.Number
=:=[A,B] or A =:= B
The compiler can provide an implicit instance of this type only when A is the same type as B. This doesn't have an equivalent syntax in a type parameter list, you'd just use the same type parameter twice.
This can be used much like <:< except that it requires the types to match exactly. This could be used to make a pair of methods mutually exclusive.
class Foo[T<:Number](x:T) {
def numOnly(implicit ev: T =:= Number) = ()
def floatOnly(implicit ev: T =:= Float) = ()
}
val asFloat = new Foo(123.0f:java.lang.Float)
asFloat.numOnly // Compile error
asFloat.floatOnly // Ok
val asNum = new Foo(123.0f:java.lang.Number)
asFloat.floatOnly // Ok
asFloat.numOnly // Compile error
Essentially if the type parameter is more specific than the constraint you can force the more specific method to be used.
<%<[A,B] or A <%< B
The compiler can provide an implicit instance of this type only when A can be converted to B. This is similar to A <% B in a type parameter list.
This requires that there is an implicit function available to turn an A into a B. This will always be possible when A <: B since the implicit A <:< B satisfies this constraint.
This class is actually marked as deprecated. It says you should instead just use A => B.
<:<, =:= and <%< are generic classes, all of them with two type parameters, and all of them extends Function1 (function with one argument). They are defined in Predef.
They are intended to supply very basic conversion as implicits. The conversions are so basic that most of the time, they are identity. The point of having those classes and not Functions is that they may be distinguished from other functions that might be in implicit scopes. Predef gives the following implicit
For every type A, a <:<[A,A] is available. As <:< is [-From, +To],
<:<[A,A] will satisfy any <:<[A,B] where A conforms to B. The
implementation is identity.
For every type A, there is also a =:=[A,A], but =:= is invariant,
so it will not satisfy any A =:= B if A is not exactly B.
implementation is identity
There is also a A <%< B each time A <% B. Implementation is the
implicit conversion implied by A <% B.
The point is not to provide clever conversions (identity is not too clever), but to provide a library level way enforce some typing constraint at compile time, similar to language level constraint <:, <%, and simple lack of type argument, (which is quite a strong constraint too), in places where the language constraints are not available. A typical example is, in a generic class, when you want a method to be available only for some value of a type parameter. Suppose Collection[A], and I want a method sort that will be available only if A <: Ordered[A]. I don't want to put the constraint in the declaration of the class, because I want to accept collections whose elements are not Ordered. I just don't want them to have a sort method. I cannot put the constraint on the method sort either, because A does not even appear as a type parameter of method sort. <:< provides a solution :
class MyCollection[A] {
def sort(implicit ev: A <:< Ordered[A])
// other methods, without constraints
}
Doing that, sort is technically available on all instances of MyCollection, but practically, when one does not pass ev parameter explicitely, it will look for an A <:< Ordered[A] in implicit scope, and conforms in predef will give one only if A is a subtype of Ordered[A]. As the (identity) conversion between A and Ordered[A] is made available in the implicit scope of the routine, A will be usable as an Ordered[A] in the body of method sort.
Using =:= would force the type to be exactly Ordered[A] (the equivalent constraint on MyCollection would be simply to make it non generic, and put the given type everywhere there is the generic parameter). <%< would ensure there is an implicit conversion. That would be the more likely one here.
Actually for this particular method sort, the proper solution would be to get an Ordering[A] in implicit context, with def sort(implicit ev: Ordering[A]) but that would not have demonstrated the point of those classes.
They are generalized type constraints for type arguments. Check out their definitions along with corresponding implicit conforms() methods in Predef.
In brief it works like this:
you add implicit parameter to your method like implicit tc: T <:< U, that works like implicit tc: <:<[T, U]
there is implicit conforms() method that returns required instance ensures that T <: U (just like with regular generics)
if T <: U is not the case, compilation of method call fails with "implicit not found"
Look at usage sample here: http://java.dzone.com/articles/using-generalized-type
An implicit question to newcomers to Scala seems to be: where does the compiler look for implicits? I mean implicit because the question never seems to get fully formed, as if there weren't words for it. :-) For example, where do the values for integral below come from?
scala> import scala.math._
import scala.math._
scala> def foo[T](t: T)(implicit integral: Integral[T]) {println(integral)}
foo: [T](t: T)(implicit integral: scala.math.Integral[T])Unit
scala> foo(0)
scala.math.Numeric$IntIsIntegral$#3dbea611
scala> foo(0L)
scala.math.Numeric$LongIsIntegral$#48c610af
Another question that does follow up to those who decide to learn the answer to the first question is how does the compiler choose which implicit to use, in certain situations of apparent ambiguity (but that compile anyway)?
For instance, scala.Predef defines two conversions from String: one to WrappedString and another to StringOps. Both classes, however, share a lot of methods, so why doesn't Scala complain about ambiguity when, say, calling map?
Note: this question was inspired by this other question, in the hopes of stating the problem in a more general manner. The example was copied from there, because it is referred to in the answer.
Types of Implicits
Implicits in Scala refers to either a value that can be passed "automatically", so to speak, or a conversion from one type to another that is made automatically.
Implicit Conversion
Speaking very briefly about the latter type, if one calls a method m on an object o of a class C, and that class does not support method m, then Scala will look for an implicit conversion from C to something that does support m. A simple example would be the method map on String:
"abc".map(_.toInt)
String does not support the method map, but StringOps does, and there's an implicit conversion from String to StringOps available (see implicit def augmentString on Predef).
Implicit Parameters
The other kind of implicit is the implicit parameter. These are passed to method calls like any other parameter, but the compiler tries to fill them in automatically. If it can't, it will complain. One can pass these parameters explicitly, which is how one uses breakOut, for example (see question about breakOut, on a day you are feeling up for a challenge).
In this case, one has to declare the need for an implicit, such as the foo method declaration:
def foo[T](t: T)(implicit integral: Integral[T]) {println(integral)}
View Bounds
There's one situation where an implicit is both an implicit conversion and an implicit parameter. For example:
def getIndex[T, CC](seq: CC, value: T)(implicit conv: CC => Seq[T]) = seq.indexOf(value)
getIndex("abc", 'a')
The method getIndex can receive any object, as long as there is an implicit conversion available from its class to Seq[T]. Because of that, I can pass a String to getIndex, and it will work.
Behind the scenes, the compiler changes seq.IndexOf(value) to conv(seq).indexOf(value).
This is so useful that there is syntactic sugar to write them. Using this syntactic sugar, getIndex can be defined like this:
def getIndex[T, CC <% Seq[T]](seq: CC, value: T) = seq.indexOf(value)
This syntactic sugar is described as a view bound, akin to an upper bound (CC <: Seq[Int]) or a lower bound (T >: Null).
Context Bounds
Another common pattern in implicit parameters is the type class pattern. This pattern enables the provision of common interfaces to classes which did not declare them. It can both serve as a bridge pattern -- gaining separation of concerns -- and as an adapter pattern.
The Integral class you mentioned is a classic example of type class pattern. Another example on Scala's standard library is Ordering. There's a library that makes heavy use of this pattern, called Scalaz.
This is an example of its use:
def sum[T](list: List[T])(implicit integral: Integral[T]): T = {
import integral._ // get the implicits in question into scope
list.foldLeft(integral.zero)(_ + _)
}
There is also syntactic sugar for it, called a context bound, which is made less useful by the need to refer to the implicit. A straight conversion of that method looks like this:
def sum[T : Integral](list: List[T]): T = {
val integral = implicitly[Integral[T]]
import integral._ // get the implicits in question into scope
list.foldLeft(integral.zero)(_ + _)
}
Context bounds are more useful when you just need to pass them to other methods that use them. For example, the method sorted on Seq needs an implicit Ordering. To create a method reverseSort, one could write:
def reverseSort[T : Ordering](seq: Seq[T]) = seq.sorted.reverse
Because Ordering[T] was implicitly passed to reverseSort, it can then pass it implicitly to sorted.
Where do Implicits come from?
When the compiler sees the need for an implicit, either because you are calling a method which does not exist on the object's class, or because you are calling a method that requires an implicit parameter, it will search for an implicit that will fit the need.
This search obey certain rules that define which implicits are visible and which are not. The following table showing where the compiler will search for implicits was taken from an excellent presentation (timestamp 20:20) about implicits by Josh Suereth, which I heartily recommend to anyone wanting to improve their Scala knowledge. It has been complemented since then with feedback and updates.
The implicits available under number 1 below has precedence over the ones under number 2. Other than that, if there are several eligible arguments which match the implicit parameter’s type, a most specific one will be chosen using the rules of static overloading resolution (see Scala Specification §6.26.3). More detailed information can be found in a question I link to at the end of this answer.
First look in current scope
Implicits defined in current scope
Explicit imports
wildcard imports
Same scope in other files
Now look at associated types in
Companion objects of a type
Implicit scope of an argument's type (2.9.1)
Implicit scope of type arguments (2.8.0)
Outer objects for nested types
Other dimensions
Let's give some examples for them:
Implicits Defined in Current Scope
implicit val n: Int = 5
def add(x: Int)(implicit y: Int) = x + y
add(5) // takes n from the current scope
Explicit Imports
import scala.collection.JavaConversions.mapAsScalaMap
def env = System.getenv() // Java map
val term = env("TERM") // implicit conversion from Java Map to Scala Map
Wildcard Imports
def sum[T : Integral](list: List[T]): T = {
val integral = implicitly[Integral[T]]
import integral._ // get the implicits in question into scope
list.foldLeft(integral.zero)(_ + _)
}
Same Scope in Other Files
Edit: It seems this does not have a different precedence. If you have some example that demonstrates a precedence distinction, please make a comment. Otherwise, don't rely on this one.
This is like the first example, but assuming the implicit definition is in a different file than its usage. See also how package objects might be used in to bring in implicits.
Companion Objects of a Type
There are two object companions of note here. First, the object companion of the "source" type is looked into. For instance, inside the object Option there is an implicit conversion to Iterable, so one can call Iterable methods on Option, or pass Option to something expecting an Iterable. For example:
for {
x <- List(1, 2, 3)
y <- Some('x')
} yield (x, y)
That expression is translated by the compiler to
List(1, 2, 3).flatMap(x => Some('x').map(y => (x, y)))
However, List.flatMap expects a TraversableOnce, which Option is not. The compiler then looks inside Option's object companion and finds the conversion to Iterable, which is a TraversableOnce, making this expression correct.
Second, the companion object of the expected type:
List(1, 2, 3).sorted
The method sorted takes an implicit Ordering. In this case, it looks inside the object Ordering, companion to the class Ordering, and finds an implicit Ordering[Int] there.
Note that companion objects of super classes are also looked into. For example:
class A(val n: Int)
object A {
implicit def str(a: A) = "A: %d" format a.n
}
class B(val x: Int, y: Int) extends A(y)
val b = new B(5, 2)
val s: String = b // s == "A: 2"
This is how Scala found the implicit Numeric[Int] and Numeric[Long] in your question, by the way, as they are found inside Numeric, not Integral.
Implicit Scope of an Argument's Type
If you have a method with an argument type A, then the implicit scope of type A will also be considered. By "implicit scope" I mean that all these rules will be applied recursively -- for example, the companion object of A will be searched for implicits, as per the rule above.
Note that this does not mean the implicit scope of A will be searched for conversions of that parameter, but of the whole expression. For example:
class A(val n: Int) {
def +(other: A) = new A(n + other.n)
}
object A {
implicit def fromInt(n: Int) = new A(n)
}
// This becomes possible:
1 + new A(1)
// because it is converted into this:
A.fromInt(1) + new A(1)
This is available since Scala 2.9.1.
Implicit Scope of Type Arguments
This is required to make the type class pattern really work. Consider Ordering, for instance: It comes with some implicits in its companion object, but you can't add stuff to it. So how can you make an Ordering for your own class that is automatically found?
Let's start with the implementation:
class A(val n: Int)
object A {
implicit val ord = new Ordering[A] {
def compare(x: A, y: A) = implicitly[Ordering[Int]].compare(x.n, y.n)
}
}
So, consider what happens when you call
List(new A(5), new A(2)).sorted
As we saw, the method sorted expects an Ordering[A] (actually, it expects an Ordering[B], where B >: A). There isn't any such thing inside Ordering, and there is no "source" type on which to look. Obviously, it is finding it inside A, which is a type argument of Ordering.
This is also how various collection methods expecting CanBuildFrom work: the implicits are found inside companion objects to the type parameters of CanBuildFrom.
Note: Ordering is defined as trait Ordering[T], where T is a type parameter. Previously, I said that Scala looked inside type parameters, which doesn't make much sense. The implicit looked for above is Ordering[A], where A is an actual type, not type parameter: it is a type argument to Ordering. See section 7.2 of the Scala specification.
This is available since Scala 2.8.0.
Outer Objects for Nested Types
I haven't actually seen examples of this. I'd be grateful if someone could share one. The principle is simple:
class A(val n: Int) {
class B(val m: Int) { require(m < n) }
}
object A {
implicit def bToString(b: A#B) = "B: %d" format b.m
}
val a = new A(5)
val b = new a.B(3)
val s: String = b // s == "B: 3"
Other Dimensions
I'm pretty sure this was a joke, but this answer might not be up-to-date. So don't take this question as being the final arbiter of what is happening, and if you do noticed it has gotten out-of-date, please inform me so that I can fix it.
EDIT
Related questions of interest:
Context and view bounds
Chaining implicits
Scala: Implicit parameter resolution precedence
I wanted to find out the precedence of the implicit parameter resolution, not just where it looks for, so I wrote a blog post revisiting implicits without import tax (and implicit parameter precedence again after some feedback).
Here's the list:
1) implicits visible to current invocation scope via local declaration, imports, outer scope, inheritance, package object that are accessible without prefix.
2) implicit scope, which contains all sort of companion objects and package object that bear some relation to the implicit's type which we search for (i.e. package object of the type, companion object of the type itself, of its type constructor if any, of its parameters if any, and also of its supertype and supertraits).
If at either stage we find more than one implicit, static overloading rule is used to resolve it.