3

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.

Kevin Meredith
  • 41,036
  • 63
  • 209
  • 384
  • possible duplicate of [What are type lambdas in Scala and what are their benefits?](http://stackoverflow.com/questions/8736164/what-are-type-lambdas-in-scala-and-what-are-their-benefits) – Kevin Wright Jan 28 '14 at 07:36
  • @KevinWright, ah, so my question about `type aliases` is actually a question about `type lamdbas`... – Kevin Meredith Jan 28 '14 at 14:20
  • Used in this way, yes, that particular alias is just part of a type lambda. – Kevin Wright Jan 28 '14 at 14:39
  • 1
    I don't think this question is about type lambdas. One needs to understand type lambdas to make sense of the meaning of `Const` here, but knowing type lambdas doesn't explain what `Const` is being used for. – Daniel C. Sobral Jan 28 '14 at 15:55

2 Answers2

2

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.

Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681
0

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.

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487