ADT,GADT和归纳类型有什么区别?


Answers:


21

代数数据类型使您可以递归定义类型。具体来说,假设我们具有数据类型

datalist=Nil|ConsofN×list

这意味着是和运算符生成的最小集合。我们可以通过定义运算符来形式化它Ñ Ç Ò Ñ 小号 ˚F X listNilConsF(X)

F(X)=={Nil}{Cons(n,x)|nNxX}

然后将定义为list

list=iNFi()

一个广义 ADT是我们所得到的,当定义一个类型运营商递归。例如,我们可以定义以下类型构造函数:

busha=Leafofa|Nestofbush(a×a)

此类型表示的元素是长度为 s的元组,持续,因为每次我们进入构造函数时,type参数都会与自身配对。因此,我们可以定义一个固定点为:a 2 n n N e s tbushaa2nnNest

F(R)=λX.{Leaf(x)|xX}{Nest(v)|vR(X)}

Coq中的归纳类型本质上是GADT,其中类型运算符的索引不限于其他类型(例如,在Haskell中),还可以通过类型理论的进行索引。这使您可以为长度索引列表指定类型,等等。


1
谢谢。但是,这不是仅仅意味着“归纳类型”与“依赖类型”完全同义吗?
ninjagecko 2012年

4
@Neel:我从未见过像bushGADT 这样的类型。我见过它们称为嵌套或非常规类型。
jbapple 2012年

3
嵌套类型是GADT的特例。GADT的关键特征仅仅是它是高级的递归定义。(对rhs的更改基本上是将类型相等性添加为构造函数的组成部分的语法糖。)
Neel Krishnaswami 2012年

4
@ninjagecko:“归纳类型”是在语义上作为构造函数的最小固定点的类型。并非所有类型都可以用这种方式描述(函数不能,无限类型(例如流)也不能)。依赖类型描述了允许程序项出现在其中的类型(即,类型可以“依赖”项)。由于Coq是从属类型理论,因此它可以让您定义的归纳类型也是从属的。但是非从属类型理论也可以支持归纳类型,并且那些归纳类型将不从属。
Neel Krishnaswami 2012年

2
@NeelKrishnaswami:您是否愿意列举枚举类型的“前几个最小”元素来澄清您的答案bush a?在这个例子中,是it Nest Leaf(a) Leaf(a) Leaf(a) Leaf(a)还是Nest ((Nest Leaf(a) Leaf(a)) (Nest Leaf(a) Leaf(a)))作为集合的一个例子?
ninjagecko 2012年

19

考虑代数数据类型,例如:

data List a = Nil | Cons a (List a)

返回类型的数据类型的每个构造都是一样的:NilCons都返回List a。如果我们允许构造函数返回不同的类型,则我们有GADT

data Empty -- this is an empty data declaration; Empty has no constructors
data NonEmpty

data NullableList a t where
    Vacant :: NullableList a Empty
    Occupied :: a -> NullableList a b -> NullableList a NonEmpty

Occupied有类型a -> NullableList a b -> NullableList a NonEmpty,而Cons有类型a -> List a -> List a。重要的是要注意这NonEmpty是一种类型,而不是术语。另一个例子:

data Zero
data Succ n

data SizedList a t where
    Alone :: SizedList a Zero
    WithFriends :: a -> SizedList a n -> SizedList a (Succ n)

具有依赖类型的编程语言中的归纳类型允许构造函数的返回类型依赖于参数的值(而不仅仅是类型)。

Inductive Parity := Even | Odd.

Definition flipParity (x:Parity) : Parity :=
  match x with
    | Even => Odd
    | Odd => Even
  end.

Fixpoint getParity (x:nat) : Parity :=
  match x with
    | 0 => Even
    | S n => flipParity (getParity n)
  end.

(*
A ParityNatList (Some P) is a list in which each member
is a natural number with parity P.
*)

Inductive ParityNatList : option Parity -> Type :=
  Nil : forall P, ParityNatList P
| Cons : forall (x:nat) (P:option Parity), 
  ParityNatList P -> ParityNatList 
  (match P, getParity x with
     | Some Even, Even => Some Even
     | Some Odd, Odd => Some Odd
     | _, _ => None
   end).

附带说明:GHC具有将值构造函数视为类型构造函数的机制。这与Coq所具有的从属归纳类型不同,但是它在某种程度上减轻了GADT的语法负担,并且可以导致更好的错误消息。


谢谢。“具有依赖类型的编程语言中的归纳类型”那么,在没有依赖类型的语言中,归纳类型会是什么样子,并且可以具有非归纳(但类似于GADT)的依赖类型吗?
ninjagecko 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.