Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 887
Kamil Kloch Avatar asked Oct 29 '25 21:10

Kamil Kloch


1 Answers

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

like image 138
pedromss Avatar answered Oct 31 '25 11:10

pedromss