10

I'm trying to understand the following piece of code (from the Scalaz library):

def kleisliIdApplicative[R]: Applicative[Kleisli[Id, R, ?]] = ...

I'm assuming that a type of the form T[P0, ?] is a type-constructor that takes a parameter. However I'm no able to find documentation that explains the usage of question marks in type parameters.

A related question is what is the difference between the question mark and an underscore?

Is there a place where all this is well-documented?

Damian Nadales
  • 4,907
  • 1
  • 21
  • 34

1 Answers1

16

The question mark syntax comes from a compiler plugin called kind-projector.

You can see it being included in the scalaz build here: https://github.com/scalaz/scalaz/blob/series/7.3.x/project/build.scala#L310

The plugin translates

Kleisli[Id, R, ?]

into (roughly)

({type L[A] = Kleisli[Id, R, A]})#L

which is a rather convoluted way (but unfortunately the only way in Scala) of expressing a type lambda, i.e. a partially applied type constructor.

Gabriele Petronella
  • 106,943
  • 21
  • 217
  • 235
  • What are you denoting here with `#L`? This expression does not compile for me in Scala 2.11 – mxk Aug 27 '16 at 14:48
  • @Matthias L is the type member defined inside the anonymous type (i.e. the {} block). It should compile, what error do you get? – Gabriele Petronella Aug 27 '16 at 14:50
  • `:1: error: ';' expected but '#' found.` `({type L[A] = Either[Int, A]})#L` ^ – mxk Aug 27 '16 at 15:30
  • i.e. it trips over the `#` – mxk Aug 27 '16 at 15:31
  • 1
    syntax looks correct, you may be using it in the wrong context? Also refer to http://stackoverflow.com/questions/8736164/what-are-type-lambdas-in-scala-and-what-are-their-benefits – Gabriele Petronella Aug 27 '16 at 17:13
  • Ah got it--I assumed you could reference the enclosed type from any context via `#`, but it only works inside a type argument list `[A, B, ...]`. Thanks. – mxk Aug 28 '16 at 09:43