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?
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?
Quotes are used to distinguish type-level constructors vs. term-level constructors of promoted types.
For instance:
By the way, the kind annotation
type MyPick :: Which
is not valid Haskell but it gives you an idea of the correspondence between the term and the type level. The closest you can get to this requires turning on another extension: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 valueX
), withX
of typeT
, 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 haveGet '[JSON,JSON,JSON] [User]
as a well-kinded expression, or evenGet '[] [User]
. Instead, we can't haveGet '[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.)