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.