I was reading the Servant documentation and came across this line:
type UserAPI = "users" :> QueryParam "sortby" SortBy :> Get '[JSON] [User]
What is the '
doing to that list?
This is DataKinds
in action, which:
This however causes confusion at the type level. Now, in types, [X]
might either be [X] :: *
, the list-of-X
type, or instead we might have [X] :: [T]
due to the lifting -- that is the value [X]
(list containing only the single value X
), with X
of type T
, lifted at the type level.
To overcome this ambiguity, GHC requires a quote in front of lifted value constructors. So, we have [X] :: *
, and '[X] :: [T]
.
Concretely, in your case, Get '[JSON] [User]
involves both the list value [JSON]
lifted to the type level, and the list type [User]
. To better appreciate the difference, note that there are no terms of type '[JSON]
, since this is not a list type. We could even have Get '[JSON,JSON,JSON] [User]
as a well-kinded expression, or even Get '[] [User]
. Instead, we can't have Get '[JSON] [User,User]
since [User,User]
is not a type.
(The type Get '[JSON,JSON,JSON] [User]
, even if it is valid, could not be meaningfully used by the Servant library. I have no idea of what that lifted list is used for in Servant.)