I've just started playing around with higher-kinded types in Scala and I'm experiencing behavior that I do not understand. I'm doing all of this in the REPL on Scala 2.9.0.1.
First I create a mapper trait so that I can map over the elements of any type M:
trait Mapper {
def mapper[M[_], A, B](m: M[A], f: A => B): M[B]
}
Here's my implementation of the mapper:
val mymapper = new Mapper {
def mapper[List, Int, Double](m: List[Int], f: Int => Double): List[Double] = m.map(f)
}
But the REPL complains...
<console>:9: error: List does not take type parameters
def mapper[List, Int, Double](m: List[Int], f: Int => Double): List[Double] = m.map(f)
^
<console>:9: error: List does not take type parameters
def mapper[List, Int, Double](m: List[Int], f: Int => Double): List[Double] = m.map(f)
^
This code works fine if I move the declaration of M[_] to be at the class level:
trait Mapper[M[_]] {
def mapper[A,B](m: M[A], f: A => B): M[B]
}
val mymapper = new Mapper[List] {
def mapper[Int, Double](m: List[Int], f: Int => Double): List[Double] = m.map(f)
}
mymapper.mapper(List(1,2,3), (x: Int) => x.toDouble)
// returns List(1.0, 2.0, 3.0)
Why is this the case? Why is that Scala can figure out the correct type for M if it's located at a class-level, but fails at the method level?
Thanks!