Skip to content
Implicit Resolution and Givens
step 1/7

Reading — step 1 of 7

Learn

~3 min readADTs, Monads, Implicits

Scala 2's implicits are the most contested feature — beloved by libraries, confusing to newcomers. Scala 3 redesigned them as given/using/extension. This lesson covers BOTH so you can read modern and legacy code.

What implicits do

Three kinds:

  1. Implicit parameters — compiler fills in arguments from context
  2. Implicit conversions — auto-convert one type to another
  3. Implicit classes — extension methods on existing types
// 1. Implicit parameter
def greet(name: String)(implicit greeting: String): String = s"$greeting, $name"

implicit val hi: String = "Hi"
println(greet("Ada"))                // "Hi, Ada" — `hi` filled in

// 2. Implicit conversion (Scala 2 — frowned upon now)
implicit def intToString(n: Int): String = s"number: $n"
val s: String = 42                   // works because of conversion

// 3. Implicit class
implicit class IntOps(n: Int) {
    def squared: Int = n * n
}
5.squared                             // 25 — extension method

Implicit resolution rules

When the compiler needs an implicit X, it searches in this order:

  1. Local scopeval/def in the current method or enclosing scope
  2. Importsimport path.implicits._ brings them into scope
  3. The companion objects of any of the types involved (X itself, base classes, type parameters)

The FIRST match wins. Ambiguity is a compile error.

This is why type classes work — you put the instance in the companion object, and the compiler finds it without explicit import.

Type classes via implicits

trait Show[A] {
    def show(a: A): String
}

object Show {
    // Default instance — found via companion object lookup
    implicit val intShow: Show[Int] = (a: Int) => s"int: $a"
    implicit val strShow: Show[String] = (a: String) => s"str: '$a'"
}

def display[A](a: A)(implicit s: Show[A]): String = s.show(a)

display(42)                  // "int: 42"
display("hello")              // "str: 'hello'"
// display(3.14)             // ERROR — no Show[Double] in scope

Context bound — shorthand

def f[A: TC](a: A) is sugar for def f[A](a: A)(implicit ev: TC[A]):

def display[A: Show](a: A): String = implicitly[Show[A]].show(a)

implicitly[T] retrieves the implicit value of type T from scope.

Scala 3: given / using / extension

Same mechanics, cleaner syntax:

// Scala 2:
implicit val intShow: Show[Int] = (a: Int) => s"int: $a"
def display[A](a: A)(implicit s: Show[A]): String = s.show(a)

// Scala 3:
given Show[Int] = (a: Int) => s"int: $a"
def display[A](a: A)(using s: Show[A]): String = s.show(a)

// Extension (replaces implicit class):
extension (n: Int)
    def squared: Int = n * n

The new keywords:

  • given — provides an implicit value
  • using — requests an implicit parameter
  • extension — adds methods to existing types

More explicit, less ambiguous than implicit everywhere.

Where implicits are essential

  • Type classes (Show, Numeric, Ordering, Functor, Monad)
  • Implicit conversions (rarely — modern style avoids these)
  • Extension methods (StringOps, IntOps, RichInt)
  • Context propagation (ExecutionContext, MDC for logging)
  • Builders / DSL marking (db transactions with implicit Connection)

Where implicits go wrong

  • Implicit conversions in user code — surprising auto-conversions. Use sparingly.
  • Long implicit chains — debugging "why doesn't this compile?" gets hard. Use -Xlog-implicits.
  • Ambiguous implicits — two equally-good candidates. Compile error; specify explicitly.
  • Imports that pull in too much — avoid import implicits._ mass imports; be selective.

Common mistakes

  • Forgetting implicit on the value — compiler can't find it without the keyword.
  • Wrong scope — implicit in nested scope but used outside; or in wrong package.
  • Implicit value doesn't match expected type — silently not found. Use implicitly[T] to debug.
  • Mixing Scala 2 and Scala 3 syntax — pick one consistent with your project.
  • Implicit conversions to common types like String — turns mismatched types silent. Avoid.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…