Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is implicit evidence in Scala? What is it good for?

I see the term "implicit evidence" in many SOF and blog posts, related to runtime retention of type information. I searched the net but have not found any simple explanation what "implicit evidence" is.

This concept comes up, for example, here.

EDIT:

A comment to Travis' nice answer:

From Predef.scala:

  sealed abstract class <:<[-From, +To] extends (From => To) 
      with Serializable

  private[this] final val singleton_<:< = 
      new <:<[Any,Any] { def apply(x: Any): Any = x }

  implicit def conforms[A]: A <:< A = singleton_<:<.asInstanceOf[A <:< A]

I don't see how the unzip's "asPair" function parameter can be derived from singleton_<:<.asInstanceOf[A <:< A]. Could someone please comment on this?

like image 599
jhegedus Avatar asked Feb 17 '14 01:02

jhegedus


1 Answers

A good example in the standard library is the definition of unzip on e.g. a List[A]:

def unzip[A1, A2](implicit asPair: (A) ⇒ (A1, A2)): (List[A1], List[A2])

The goal is to allow the following to compile:

val (ks, vs) = List('a -> 1, 'b -> 2, 'c -> 3).unzip

But not this:

val (ks, vs) = List(1, 2, 3).unzip

This is accomplished via an implicit argument that witnesses that the type of the list can be viewed as a pair. In the example above this evidence is provided by Predef.conforms, which for any type A will implicitly provide an instance of A <:< A, which is a subtype of A => A. The instance provided by conforms will of course just be the identity function.

If you look at the definition of unzip, you'll see how the evidence is used in this case:

def unzip[A1, A2](implicit asPair: A => (A1, A2)): (CC[A1], CC[A2]) = {
    val b1 = genericBuilder[A1]
    val b2 = genericBuilder[A2]
    for (xy <- sequential) {
      val (x, y) = asPair(xy)
      b1 += x
      b2 += y
    }
    (b1.result, b2.result)
  }

I.e., it's used to deconstruct the items in the sequence. Remember that this method is defined on any List[A], so writing plain old val (x, y) = xy wouldn't compile.

Other applications of implicit evidence may have different goals (some quite complex) and may use the implicit evidence in different ways (it's not necessarily just a function), but the basic pattern is generally going to be more or less the same as what you see with unzip.

like image 150
Travis Brown Avatar answered Sep 21 '22 20:09

Travis Brown