Partially Applying Scala type variables
Below is a neat trick that others may find useful when designing APIs using the Scala programming language.
Scala’s type inferencer is not as clever as some. As a result, we often find ourselves explicitly annotating type variables in certain contexts. This can become a little annoying, but what is worse, is if you have a type variable list and only one of those requires explicit specification, the others must also be explicitly specified even though they would have otherwise been inferred.
Let me demonstrate. I will use Scala’s higher-kinds, which are never inferred (this is quite acceptable given the problems associated with inferring higher-kinds — consider Java and C# where they do not even exist, thus leading to an enormous repetitive chore) though other examples may be applicable. However, it can be annoying if you were to write say, the Monad join function:
def join[M[_], A](m: M[M[A]]): M[A] = error("todo")
A caller invocation might look like:
val x = join[List, Int](List(List(1, 2, 3), List(4, 5, 6)))
Notice the explicit annotation with the List type constructor, however, the second type variable (Int) must also be explicitly specified, even though it could have otherwise been inferred. This is a bit annoying.
We can do away with it like so:
def join[M[_]] = new { def apply[A](m: M[M[A]]): M[A] = error("todo") }
And now the caller code no longer has that clumsy type annotation:
val x = join[List](List(List(1, 2, 3), List(4, 5, 6)))
Yay! Have a nice day ![]()
September 23rd, 2008 at 4:08 am
Hi Tony,
can you explain what M[_] means?
Thanks.
Channing
September 23rd, 2008 at 11:12 am
Hi Channing, that is a type variable of a higher kind. It means you can pass in a type constructor that matches that kind. The kind being, that it takes one more type argument. For example, you can use
Listbecause it takes one more type argument, but you couldn’t useString,Int,EitherorList[Int]as the type value for M[_] since they don’t accept one (and only one) type variable.I hope this helps