Daniel Shin
Daniel Shin

Reputation: 5206

Scala implicit object vs implicit val

I've seen two ways (one less than the other) of declaring implicit for typeclass pattern in Scala.

implicit val instance1 = new Typeclass { def do = ??? }
implicit object instance2 extends Typeclass { def do = ??? }

How are they different? Should one prefer one to the other for certain times? I find implicit val much more commonly used than implicit object and I've yet to find many resources about implicit object.

Upvotes: 23

Views: 3156

Answers (1)

Jason Scott Lenderman
Jason Scott Lenderman

Reputation: 1918

One difference is that the object version is going to be lazily initialized, i.e. it's constructor will not be called until the first time it is used. For example:

trait Incrementer[T] {
  def inc(x: T)
}

def increment[T](x: T)(implicit ev: Incrementer[T]) = ev.inc(x)

implicit object IntIncrementer extends Incrementer[Int] {
  println("IntIncrementer is being constructed...")

  def inc(x: Int) = x + 1
}

implicit val DoubleIncrementer extends Incrementer[Double] {
  println("DoubleIncrementer is being constructed...")

  def inc(x: Double) = x + 1D
}

Note that you will not see the message from IntIncrementer until it is used, e.g.

increment(1)  //this prints "IntIncrementer is being constructed..."

The message from DoubleIncrementer, however, will be displayed when it is defined. So the initialization of implicit object is lazy while the initialization of implicit val is strict.

Upvotes: 16

Related Questions