什么是Haskell的DataKinds扩展?

时间:2013-12-13 03:36:23

标签: haskell data-kinds

我试图找到一个对DataKinds扩展的解释,这对我来说只有阅读Learn You a Haskell才有意义。是否有一个标准的来源,对我来说只有我学到的东西才有意义?

编辑:例如documentation

  

使用-XDataKinds,GHC会自动提升每种合适的数据类型   成为一种,它的(值)构造函数是类型构造函数。   以下类型

并给出了示例

data Nat = Ze | Su Nat

产生以下种类和类型构造函数:

Nat :: BOX
Ze :: Nat
Su :: Nat -> Nat

我没有明白这一点。虽然我不明白BOX的含义,但Ze :: NatSu :: Nat -> Nat语句似乎表明Ze和Su通常就是正常数据构造函数的情况,正如您所期望的那样看看ghci

Prelude> :t Su
Su :: Nat -> Nat

2 个答案:

答案 0 :(得分:56)

好吧,让我们从基础开始

种类是类型*,例如

Int :: *
Bool :: *
Maybe :: * -> *

请注意,->在类型级别上被重载为“函数”。所以*是一种普通的Haskell类型。

我们可以要求GHCi使用:k打印某种内容。

数据种类

现在这不是很有用,因为我们无法自己制作!使用DataKinds时,我们写

 data Nat = S Nat | Z

GHC将促进此操作以创建相应类型Nat

 S :: Nat -> Nat
 Z :: Nat

所以DataKind使得类型系统可扩展。

用途

让我们使用GADTs来做原型种类的例子

 data Vec :: Nat -> * where
    Nil  :: Vec Z
    Cons :: Int -> Vec n -> Vec (S n)

现在我们看到我们的Vec类型按长度编制索引。

这是10k英尺的基本概述。

**这实际上还在继续,Values : Types : Kinds : Sorts ...有些语言(Coq,Agda ..)支持这个无限的宇宙堆栈,但是Haskell将所有东西都归为一类。

答案 1 :(得分:37)

这是我的看法:

考虑长度索引的Vector类型:

data Vec n a where
  Vnil  :: Vec Zero a
  Vcons :: a -> Vec n a -> Vec (Succ n) a

data Zero
data Succ a

我们有一个Vec :: * -> * -> *种。因为您可以通过以下方式表示Int的零长度Vector:

Vect Zero Int

您还可以声明无意义的类型:

Vect Bool Int

这意味着我们可以在类型级别进行无类型的函数式编程。因此,我们通过引入数据类型来消除这种模糊性,并且可以具有这样的类型:

Vec :: Nat -> * -> *

现在我们的Vec获取一个名为Nat的DataKind,我们可以将其声明为:

datakind Nat = Zero | Succ Nat

通过引入新的数据种类,没有人可以声明无意义的类型,因为Vec现在具有更受约束的种类签名。