请参阅上的官方用户手册页面数据类型和模式匹配获取此页面上信息的最新版本。
本文档是从一个有文字的Agda文件中提取的,该文件已使用Agda 2.3.0进行了测试
目录
- 示例数据类型
- 一般形式
- 严格的积极性
- 形成和引入规则
- 通过模式匹配进行定义
- 消除和平等规则
- 大规模淘汰
- 超出淘汰规则
- 大型感应式
示例数据类型
在引言中,我们已经展示了自然数数据类型的定义(以一元表示法):
data Nat:设置位置零:自然例如:Nat->Nat
我们再举几个例子。首先是真值的数据类型:
data Bool:设置位置真:布尔假:布尔
然后设置单位:
data True:设置位置tt:正确
True集合表示平凡的真命题。
data False:设置位置
False集没有构造函数,因此没有元素。它代表了一个微不足道的错误命题。
另一个示例是叶子中带有自然数的非空二叉树的数据类型:
data BinTree:设置位置叶子:Nat->BinTree分支:BinTree->BinTree->BinTree
最后,Brouwer序数的数据类型:
数据命令:设置位置zeroOrd:命令sucOrd:订单->订单限制命令:(自然->命令)->命令
一般形式
简单数据类型D定义的一般形式如下
data D:设置位置c(c)1:A1...c(c)n个:An个
数据类型的名称D和名称c1, ..., c(c)n个构造函数必须是新的,写入当前签名和上下文。
Agda检查A1, ..., A类n个:设置当前签名和上下文。此外,每个A我有表单
(年1:B1) -> ... -> (年米:B米)->D
其中参数类型为B我构造函数的
- 非传导性的(a)侧面状况)根本没有提到D,
- 或感应的并具有表单
(z)1:C1) -> ... -> (z)k个:Ck个)->D
其中D不能出现在任何C中j个.
严格的积极性
D不能出现在任何C中的条件j个也可以用D来表示严格肯定在B中我.
Agda可以检查这种阳性情况。
严格的积极条件排除了如下声明
数据错误:设置位置坏:(坏->坏)->坏A、B、C--A处于负位置,B和C正常
因为构造函数的参数类型中出现了Bad的负值。(请注意,Bad的相应数据类型声明在Haskell和ML等标准函数语言中是允许的。)。非严格正声明被拒绝,因为可以使用它们编写非终止函数。
要查看如何使用上面的Bad数据类型编写循环定义,请参阅巴丁·哈斯克尔.有关终止的更多一般信息,请参见总数.
形成和引入规则
上述数据类型I的声明生成一个类型
D:设置
它被称为形成规则Martin-Löf型理论中的D。同样,施工人员的类型
c(c)1:A1...c(c)n个:An个
被称为引言规则Martin-Löf型理论中的I。
通过模式匹配进行定义
声明数据类型后,可以通过元素上的模式匹配来定义函数。这里有一些例子。
_+_:自然->自然->自然m+零=mm+sucn=suc(m+n)不是:布尔->布尔不正确=错误not false=真_+“_:订单->订单->订单m+'zeroOrd=mm+'成功命令n=成功命令(m+'n)m+'limOrd f=limOrt(\n->m+'f n)
Agda有一个用于在空类型上进行模式匹配的特殊工具。例如,我们可以将一个函数从空集定义为任意其他集:
空函数:(C:Set)->False->C空函数C()
这是通过False元素上的模式匹配来定义的。由于此类型没有元素,因此没有事例。Agda用第二行表示这一点,它告诉系统这是由没有案例关于第二个论点。
消除和平等规则
所有这些情况都是“结构递归”(在一个参数中)在定义给定数据类型的元素的方式上的例子。对于每个正确的数据类型声明,我们可以将一个常量(递归或消除常数)它表达了结构的一般原理数据类型的递归。每个这样的常量都是通过模式匹配定义的:
钠:(C:Nat->Set)->C zero->((x:Nat)->C x->C(suc x))->(z:Nat钠C d e zero=d钠C d e(sucn)=e n(钠C d en)如果:(C:Bool->Set)->C true->C false->(z:Bool)->C z如果C d e为真=d如果C d e false=e一种情况:(C:True->Set)->Ctt->(z:True)->Cz一种情况C d tt=dnocase:(C:False->Set)->(z:False)->Cznocase C()酶ordrec:(C:Ord->Set)->C zeroOrd->((x:Ord)->C x->C(sucOrd x))->((f:Nat->Ord)->(x:Nat)->C(f x))->C(limOrd f)->(z:Ordordrec C d e g zeroOrd=dordrec C d e g(sucOrd a)=e a(ordrec C d e g a)ordrec数据段(limOrd f)=g f(\x->ordrec C数据段(f x))
这些常数的类型称为消除规则在Martin-Löf型理论中,定义方程被称为等式规则.
大规模淘汰
我们也可以通过结构递归来定义集合。以下是将Bool中的元素转换为相应Set的函数的定义:
isTrue:Bool->设置isTrue true=真isTrue false=假
我们甚至可以定义大的上述消除常数的版本。例如,
如果1:(C:Bool->Set1)->C真->C假->(z:Bool)->C z如果1 C d e真=d如果1 C d e false=e
超出淘汰规则
Agda的模式匹配在一个参数中超越了通常的结构递归概念。
例如,我们可以通过对两个参数进行模式匹配来定义函数_===_:自然->自然->布尔zero==zero=真zero==suc n=falsesuc m==零=假suc m==suc n=m==n
递归调用通常可以打开结构较小的参数:
一半:Nat->Nat半零=零半(例如零)=零半(suc(sucn))=suc(半n)
Agda允许通过模式匹配对递归函数进行相当一般的定义。终止检查器(用于检查尺寸变化终端Jones等人)并提供了覆盖率检查器,但我们将其描述推迟到稍后-请参阅总数.
大型感应式
Agda还允许定义大的归纳类型,例如
data Large:设置1,其中El:设置->大型箭头:大->大->大
由于类型Set上的Large ranges的构造函数之一,Large不能是Set的成员,但必须属于下一个universe Set1。
通常,要在Set(i+1)中定义数据类型,所有构造函数类型都必须在Seti中。