Jay Taylor's notes

back to listing index

implicits - Scala Identifier "implicitly" - Stack Overflow

[web search]
Original source (stackoverflow.com)
Tags: scala manifests implicits implicit evidence stackoverflow.com
Clipped on: 2012-09-25

I have seen a function named implicitly used in Scala examples, what is it and how is it used?

Example here:

scala> sealed trait Foo[T] { def apply(list : List[T]) : Unit }; object Foo {
     
|         implicit def stringImpl = new Foo[String] {
     
|           def apply(list : List[String]) = println("String")
     
|         }
     
|         implicit def intImpl = new Foo[Int] {
     
|           def apply(list : List[Int]) =  println("Int")
     
|         }
     
|       } ; def foo[A : Foo](x : List[A]) = implicitly[Foo[A]].apply(x)
defined
trait Foo
defined module
Foo
foo
: [A](x: List[A])(implicit evidence$1: Foo[A])Unit

scala
> foo(1)
<console>:8: error: type mismatch;
 found  
: Int(1)
 required
: List[?]
       foo
(1)
           
^    
scala
> foo(List(1,2,3))
Int
scala
> foo(List("a","b","c"))
String
scala
> foo(List(1.0))
<console>:8: error: could not find implicit value for evidence parameter of type
 
Foo[Double]
       foo
(List(1.0))
         
^

Note that we have to write implicitly[Foo[A]].apply(x) since the compiler thinks that implicitly[Foo[A]](x) means that we call implicitly with parameters.

asked Oct 4 '10 at 13:21
Image (Asset 1/4) alt= 4,76021945

93% accept rate
add comment

3 Answers

up vote 46 down vote accepted

Here are a few reasons to use the delightfully simple method implicitly.

To understand/troubleshoot Implicit Views

An Implicit View can be triggered when the prefix of a selection (consider for example, the.prefix.selection(args) does not contain a member selection that is applicable to args (even after trying to convert args with Implicit Views). In this case, the compiler looks for implicit members, locally defined in the current or enclosing scopes, inherited, or imported, that are either Functions from the type of that the.prefix to a type with selection defined, or equivalent implicit methods.

scala> 1.min(2) // Int doesn't have min defined, where did that come from?                                   
res21
: Int = 1

scala
> implicitly[Int => { def min(i: Int): Any }]
res22
: (Int) => AnyRef{def min(i: Int): Any} = <function1>

scala
> res22(1) //
res23
: AnyRef{def min(i: Int): Int} = 1

scala
> .getClass
res24
: java.lang.Class[_] = class scala.runtime.RichInt

Implicit Views can also be triggered when an expression does not conform to the Expected Type, as below:

scala> 1: scala.runtime.RichInt
res25
: scala.runtime.RichInt = 1

Here the compiler looks for this function:

scala> implicitly[Int => scala.runtime.RichInt]
res26
: (Int) => scala.runtime.RichInt = <function1>

Accessing an Implicit Parameter Introduced by a Context Bound

Implicit parameters are arguably a more important feature of Scala than Implicit Views. They support the type class pattern. The standard library uses this in a few places -- see scala.Ordering and how it is used in SeqLike#sorted. Implicit Parameters are also used to pass Array manifests, and CanBuildFrom instances.

Scala 2.8 allows a shorthand syntax for implicit parameters, called Context Bounds. Briefly, a method with a type parameter A that requires an implicit parameter of type M[A]:

def foo[A](implicit ma: M[A])

can be rewritten as:

def foo[A: M]

But what's the point of passing the implicit parameter but not naming it? How can this be useful when implementing the method foo?

Often, the implicit parameter need not be referred to directly, it will be tunneled through as an implicit argument to another method that is called. If it is needed, you can still retain the terse method signature with the Context Bound, and call implicitly to materialize the value:

def foo[A: M] = {
   
val ma = implicitly[M[A]]
}

Passing a subset of implicit parameters explicitly

Suppose you are calling a method that pretty prints a person, using a type class based approach:

trait Show[T] { def show(t: T): String }
object Show {
 
implicit def IntShow: Show[Int] = new Show[Int] { def show(i: Int) = i.toString }
 
implicit def StringShow: Show[String] = new Show[String] { def show(s: String) = s }

 
def ShoutyStringShow: Show[String] = new Show[String] { def show(s: String) = s.toUpperCase }
}

case class Person(name: String, age: Int)
object Person {
 
implicit def PersonShow(implicit si: Show[Int], ss: Show[String]): Show[Person] = new Show[Person] {
   
def show(p: Person) = "Person(name=" + ss.show(p.name) + ", age=" + si.show(p.age) + ")"
 
}
}

val p = Person("bob", 25)
implicitly
[Show[Person]].show(p)

What if we want to change the way that the name is output? We can explicitly call PersonShow, explicitly pass an alternative Show[String], but we want the compiler to pass the Show[Int].

Person.PersonShow(si = implicitly, ss = Show.ShoutyStringShow).show(p)
answered Oct 4 '10 at 22:05
Image (Asset 2/4) alt= 26.4k257114
2 upvote
 flag
You should add that answer here stackoverflow.com/q/1025181/203968 – oluies Oct 11 '10 at 9:06
add comment

Implicitly is avaliable in Scala 2.8 and is defined in Predef as:

def implicitly[T](implicit e: T): T = e

It is commonly used to check if an implicit value of type T is available and return it if so is the case.

Simple example from retronyms presentation )

scala> implicit val a = "test" // define an implicit value of type String
a
: java.lang.String = test
scala
> val b = implicitly[String] // search for an implicit value of type String and assign it to b
b
: String = test
scala
> val c = implicitly[Int] // search for an implicit value of type Int and assign it to c
<console>:6: error: could not find implicit value for parameter e: Int
       
val c = implicitly[Int]
                         
^
Image (Asset 3/4) alt= 30125
answered Oct 4 '10 at 13:22
Image (Asset 4/4) alt= 4,76021945
2 upvote
 flag
The method doesn't exactly check; it seems to cause a compile error if there isn't an implicit value available and, if there is, seems to retrieve it. Can you provide some more context on why I'd ever want to use this? – davetron5000 Oct 4 '10 at 21:20
4 upvote
 flag
implicitly[Ordering[(Int, String)]].compare( (1, "b"), (1, "a") ), especially to retrieve an implicit parameter introduced by a Context Bound: def foo[A: Ordering](a1: A, a2: A) = implicitly[Ordering[A]].compare(a1, a2) – retronym Oct 4 '10 at 21:24
  upvote
 flag
You have no idea how incredibly helpful this simple answer was for me. Thank you for spelling it out like this. – Dan Burton Nov 24 '11 at 18:56
add comment

A "teach you to fish" answer is to use the alphabetic member index currently available in the Scaladoc nightlies. The letters (and the #, for non-alphabetic names) at the top of the package / class pane are links to the index for member names beginning with that letter (across all classes). If you choose I, e.g., you'll find the implicitly entry with one occurrence, in Predef, which you can visit from the link there.

answered Oct 4 '10 at 13:50
Randall Schulz
9,89111635
  upvote
 flag
Ahh, thanks. It was not in the search index && I have not clicked on the "the letters" earlier. (but I found it in predef somehow anyway). Always good to learn something about Scala. – oluies Oct 4 '10 at 14:00
7 upvote
 flag
Of course, those scaladocs say nothing at all about implicitly, so that hardly counts as documentation. How would someone figure out what that method does from those docs alone? I feel routinely let down by the Scala documentation. The behavior of methods like implicitly are far from obvious, and the documentation on them is barely better than nonexistent. Thank god for Stack Overflow. /end rant – Jeff Oct 4 '10 at 17:46
1 upvote
 flag
4 upvote
 flag
The type signature documents this one pretty well. – retronym Oct 4 '10 at 19:11
add comment

Your Answer

 
community wiki

Not the answer you're looking for? Browse other questions tagged or ask your own question.