我正在阅读Servant 文档并遇到了这一行:
type UserAPI = "users" :> QueryParam "sortby" SortBy :> Get '[JSON] [User]
Run Code Online (Sandbox Code Playgroud)
什么是'做这一名单?
引号用于区分类型级构造函数与已提升类型的术语级构造函数.
例如:
{-# LANGUAGE DataKinds #-}
data Which = One | Two
myPick :: Which -- Type
myPick = One
type MyPick :: Which -- Kind
type MyPick = 'One
Run Code Online (Sandbox Code Playgroud)
顺便说一下,类型注释type MyPick :: Which不是有效的Haskell,但它让你了解术语和类型级别之间的对应关系.你可以得到最接近的另一个扩展:
{-# LANGUAGE TypeFamilies #-}
type family MyPick :: Which where
MyPick = 'One
Run Code Online (Sandbox Code Playgroud)
这是DataKinds在行动,其中:
然而,这会在类型级别引起混淆.现在,在类型中,[X]可能是[X] :: *,X类型列表,或者我们可能[X] :: [T]由于提升 - 这是值[X](仅包含单个值的列表X),X类型T,在类型级别提升.
为了克服这种模糊性,GHC需要在提升价值构造者面前引用.所以,我们有[X] :: *,和'[X] :: [T].
具体来说,在您的情况下,Get '[JSON] [User]涉及[JSON]提升到类型级别的列表值和列表类型[User].为了更好地理解差异,请注意没有类型的术语'[JSON],因为这不是列表类型.我们甚至可以Get '[JSON,JSON,JSON] [User]作为一个良好的表达,甚至Get '[] [User].相反,我们不能拥有,Get '[JSON] [User,User]因为[User,User]不是一种类型.
(该类型Get '[JSON,JSON,JSON] [User],即使它是有效的,也不能被Servant库有意义地使用.我不知道在Servant中使用了什么提升列表.)