I'm trying to set a view bound over a high-kinded type and I get an error message that I cannot understand.
$ scala -language:higherKinds
Welcome to Scala version 2.10.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_43).
Type in expressions to have them evaluated.
Type :help for more information.
scala> trait F[M[_]]
defined trait F
scala> def foo[M[_]](implicit m: M[_] => F[M]) = 42
foo: [M[_]](implicit m: M[_] => F[M])Int
scala> def bar[M[_] <% F[M]] = 42
<console>:8: error: type M takes type parameters
def bar[M[_] <% F[M]] = 42
^
Shouldn't bar
compile to the same thing as foo
? What am I missing?
Note that there's a subtle distinction between the M[_]
in the type parameter list and the type M[_]
(i.e., the role the M[_]
plays in the function type in the implicit parameter list). The first is a type constructor parameter and the second is an existential type (see sections 4.4 and 3.2.10 of the Scala language specification for more information).
So for example we could replace the type constructor parameter M[_]
with M[X]
without changing the meaning, but this would be a syntax error in the latter case (which is shorthand instead for something like M[X] forSome { type X }
).
The difference may be clearer in the following example (which compiles just fine):
scala> def bar[M[_], M_ <: M[_] <% F[M]] = 42
bar: [M[_], M_ <: M[_]](implicit evidence$1: M_ => F[M])Int
Here the first M[_]
is a type constructor parameter, and the second (the upper bound on M_
) is an existential type.
The Scala compiler could conceivably make M[_] <% F[M]
work as you expect it to here—i.e., it could translate the type constructor parameter into an existential type in the type of the implicit parameter that it creates for the context bound—but that would require an extra little piece of compiler magic, and there's already enough of that to go around.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With