列表前面的撇号('[Something])在Haskell中意味着什么?

Mar*_*oni 11 haskell servant

我正在阅读Servant 文档并遇到了这一行:

type UserAPI = "users" :> QueryParam "sortby" SortBy :> Get '[JSON] [User]
Run Code Online (Sandbox Code Playgroud)

什么是'做这一名单?

gal*_*ais 9

引号用于区分类型级构造函数与已提升类型的术语级构造函数.

例如:

{-# 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)


chi*_*chi 7

这是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中使用了什么提升列表.)