Reputation: 41909
Reading Functional Programming in Scala, I saw the following type alias:
type Const[M, B] = M
implicit def monoidApplicative[M](M: Monoid[M]) =
new Applicative[({ type f[x] = Const[M, x] })#f] {
def unit[A](a: => A): M = M.zero
def map2[A,B,C](m1: M, m2: M)(f: (A,B) => C): M = M.op(m1,m2)
}
What's the meaning of the Const[M, x]
here as a type alias? My understanding is that, for the new Applicative
being created, it has a [M, B]
type where the B
is specified at the function level.
Upvotes: 3
Views: 1964
Reputation: 297155
I'm not sure why this type alias was introduced -- good reason to go back to that book! :)
However, the meaning is simple. Const
is something with two type parameters where the second type parameter doesn't matter. I'd expect it to be used somewhere that expects a type constructor with two type parameters, but, as it happens, it is not.
The expression ({ type f[x] = Const[M, x] })#f
is known as a type lambda, and it is used here (and in most places, as a matter of fact) to convert something that takes two type parameters, Const
, into something that takes one type parameter!
Now, the interesting thing is that the type parameter being received is ignored, due to its position in Const
, and, instead, M
, which is a type parameter of the monoidApplicative
definition, is used.
Note that Applicative
expects something that takes a type parameter, and here we are working with an M
where Monoid[M]
exists. Two examples of such M
would be Int
and String
, neither of which has a type parameter.
So, in a sense, we are cheating Applicative
by a trick where the type parameter is ignored and the final type gets replaced by whatever you want, so you could have an Applicative[Int]
, so to speak, despite Int
not having a type parameter.
Upvotes: 2
Reputation: 170713
Const[M, x]
doesn't have any special meaning, you could equivalently inline its definition and write { type f[x] = M }
. ({ type f[x] = Const[M, x] })#f
defines a type-level function.
Upvotes: 0