从Servant论文中了解'echo'服务示例API

时间:2017-06-08 17:34:26

标签: api haskell servant

servant paper的介绍包含以下示例API类型:

type Echo = "echo"
          :> ReqBody ’[PlainText] String
          :> Get ’[PlainText] String

我试图理解这个例子。它似乎是定义一个类型的同义词,但似乎涉及一些我以前从未见过的事情。

以下是我提出的三个问题:

  1. 如何在类型定义中使用字符串文字?
  2. "echo"是一个字符串文字。我认为这些仅用于定义特定字符串,并且在类型声明中使用时不知道这意味着什么。

    1. 什么是符号:>
    2. “servant”包中此符号的定义似乎是defined here,如下所示:

      data (path :: k) :> a
          deriving (Typeable)
      infixr 9 :>
      

      我猜想:>对应于api字符串中的/,但是看不出这个定义会如何实现。

      这是我第一次看到除函数类型->以外的非字母数字类型。

      1. 列表类型之前的撇号是什么意思?
      2. [PlainText]我理解只是代表一个PlainText元素列表,但相反我不明白’[PlainText]的含义。

1 个答案:

答案 0 :(得分:1)

  

类型定义中有一个字符串文字吗?

DataKinds扩展名允许您在类型签名中使用这些字符串文字。它们中的每一个代表不同的类型。他们都属于那种Symbol;我们可以使用ghci中的:kind命令来测试它:

Prelude> :set -XDataKinds
Prelude> :kind "foo"
"foo" :: GHC.Types.Symbol

因为在Haskell中只有类型*具有值,所以这些类型级别的字符串不是有人值守的。但是functions可以让你获得相应的术语级别字符串。

  

符号是什么:>?

TypeOperators扩展名允许您使用运算符名称定义类型。这对于主要用于组合其他类型的参数化类型很有用。请注意,:>有两个类型参数但没有值级构造函数:它仅在类型级别使用。

  

列表类型之前的撇号是什么意思?

DataKinds不只是启用符号。它允许您将值构造函数用作 types ,并且这些构造函数的类型依次变为 types 。例如:

Prelude> :set -XDataKinds
Prelude> :kind True
True :: Bool

这些推广的构造函数不会被任何术语居住(因为它们具有*以外的种类。)

特别是,我们可以将列表提升为类型级别。但这会产生一些含糊之处。签名中的[Int]是什么?它是Int的列表类型(具有种类*)还是具有一个元素的类型级列表,类型Int?撇号表明我们正在讨论类型级列表。

Prelude> :set -XDataKinds
Prelude> :kind [Int]
[Int] :: *
Prelude> :kind '[Int]
'[Int] :: [*]
Prelude> :kind '[True]
'[True] :: [Bool]

多个元素的类型级列表不需要撇号,因为没有歧义:

Prelude> :kind [Int,Int]
[Int,Int] :: [*]