Search code examples
scalaimplicit-conversionimplicit

Confusion about implicit example in scala


implicit def list2ordered[A](x: List[A])(implicit elem2ordered: A => Ordered[A]): Ordered[List[A]] =
  new Ordered[List[A]] {
    //replace with a more useful implementation
    def compare(that: List[A]): Int = 1
}

println(List(1,2,3) <= List(4,5))

Can not understand how it work


Solution

  • List(1,2,3) <= List(4,5)
    

    is desugared to

    list2ordered(List(1, 2, 3))(Predef.intWrapper) <= List(4, 5)
    

    The signature of list2ordered

    implicit def list2ordered[A](x: List[A])(implicit elem2ordered: A => Ordered[A]): Ordered[List[A]]
    

    means that it's a conditional implicit conversion, namely, you have an implicit conversion List[A] => Ordered[List[A]] provided you have an implicit conversion A => Ordered[A].

    And Predef.intWrapper is precisely such an implicit conversion because it's Int => RichInt and RichInt extends Ordered[Int] (RichInt <: ScalaNumberProxy[Int] <: OrderedProxy[Int] <: Ordered[Int]).

    You can always see how implicits were resolved with reify

    import scala.reflect.runtime.universe._
    println(reify{List(1,2,3) <= List(4,5)}.tree)
    //App.this.list2ordered(List.apply(1, 2, 3))(((x) => Predef.intWrapper(x))).$less$eq(List.apply(4, 5))