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

时间:2017-07-01 20:08:35

标签: haskell servant

我正在读仆人documentation并且遇到了这句话:

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

'对该列表做了什么?

2 个答案:

答案 0 :(得分:9)

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

例如:

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

答案 1 :(得分:7)

这是DataKinds,其中:

  • 提升类型级别的值,
  • 将类型提升到种类级别

然而,这会在类型级别引起混淆。现在,在类型中,[X]可能是[X] :: *,列表 - X类型,或者我们可能会[X] :: [T]由于解除而来 - 这就是值[X](仅包含单个值X的列表),类型为X的{​​{1}},在类型级别解除。

为了克服这种模糊性,GHC需要在提升价值构造者面前引用。因此,我们有T[X] :: *

具体而言,在您的情况下,'[X] :: [T]涉及提升到类型级别的列表值Get '[JSON] [User]和列表类型[JSON]。为了更好地理解差异,请注意,没有[User]类型的术语,因为这不是列表类型。我们甚至可以将'[JSON]作为一个良好的表达方式,甚至是Get '[JSON,JSON,JSON] [User]。相反,我们不能Get '[] [User]因为Get '[JSON] [User,User]不是类型。

(类型[User,User],即使它是有效的,也不能被Servant库有意义地使用。我不知道在Servant中使用了哪个提升列表。)