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

What does an apostrophe in front of a list ( '[Something] ) mean in Haskell?

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

type UserAPI = "users" :> QueryParam "sortby" SortBy :> Get '[JSON] [User]

' 对该列表做了什么?

引号用于区分类型级构造函数和提升类型的术语级构造函数。

例如:

{-# LANGUAGE DataKinds #-}

data Which = One | Two

myPick :: Which -- Type
myPick = One

type MyPick :: Which -- Kind
type MyPick = 'One

顺便说一句,种类注释 type MyPick :: Which 无效 Haskell 但它可以让您了解术语与类型级别之间的对应关系。最接近此的需要打开另一个扩展程序:

{-# LANGUAGE TypeFamilies #-}

type family MyPick :: Which where
  MyPick = 'One

这是 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 中有什么用。)