Search code examples
scalaimplicitsubtypescalac

Implicit resolution choosing the most specific subtype


Can some one explain me why scala resolve the most generic implicit no matter of local scope implicit more specific ?

Example:

import scala.math.ScalaNumber

type Serializer[T] = T => String

object SerializedOps{
  implicit class AnyOps[T](t: T){
    def serialize(implicit s: Serializer[T]) : String = s(t)
  }
}

object Instances{
  implicit val scalaNumber : Serializer[ScalaNumber] = _.toString + "_DEFAULT"
}


import SerializedOps._
import Instances._


implicit val bigDecimalCustom : Serializer[BigDecimal] = _.toString + "_CUSTOM"

val res: String = BigDecimal(100).serialize
//res: String = 100DEFAULT

Why i can't define a new implicit more specific in my local scope? How scala resolve implicits ?


Solution

  • Subtype does win:

    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.

    however function is contravariant over its argument type which makes

    ScalaNumber => String
    

    a subtype of

    BigDecimal => String
    

    thus ScalaNumber => String is more specific. Note that type Serializer[T] = T => String is aliasing a function type.