scalatype-aliasimplicits

Scala implicit conversion for type aliases


Define

type TA[T] = T => Int

implicit class TAOps[T](a: TA[T]) {
  def foo(): Unit = {println("TA")}
}

val ta: TA[Double] = x => x.toInt

Now,

ta.foo()

fails to compile with the message value foo is not a member of ammonite.$sess.cmd1.TA[Double],

while the explicit call

TAOps(ta).foo()

prints TA. Why does the implicit conversion not work in the former case?


Solution

  • Your implicit def is expecting a type that receives one type parameter, i.e. a TA[T]

    Your declaration: val ta: TA[Double] = ... is a type it self, and doesn't take any type parameters. So the compiler will not use your implicit def to type check this.

    Conclusion you have an implicit type conversion for a type that takes a type parameter and TA[Double] doesn't take any type parameters.

    Solutions:

    1 - Replace the implicit type conversion to receive a Function1:

      implicit class TAOps[T](a: T => Int) {
        def foo: Unit = {
          println("TA")
        }
      }
    

    2 - Use type lambdas:

      implicit class TAOps[T](a: ({type Alias = TA[T]})#Alias) {
        def foo: Unit = {
          println("TA")
        }
      }
    

    Here the type you created is curried. So the compiler will now apply this implicit conversions to types that match, it is no longer expecting a type that receives 1 type parameter.

    More on Type Lambdas