请参见官方用户手册获取此页面上信息的最新版本。
总有机碳
基本示例
我们从简单的数据类型开始,然后逐步引入更复杂的情况:参数化数据类型、数据类型的索引族(“归纳族”)和归纳递归数据类型。
简单数据类型
数据类型由引入数据
声明。也许最基本的例子是自然数的类型。其定义如下:
data-Nat:设置位置零:自然例如:Nat->Nat
在这里国家
是要定义的类型的名称,并且零
和苏克
是施工人员. 这种类型称为感应的,因为直观地说,类型定义了包含元素的“最小”集零
并在函数下关闭苏克
,人们可以通过归纳法证明此类集合的性质。类型的元素示例国家
是零
,(吸零)
,(例如(例如零))
归纳类型上的函数可以使用模式匹配和结构递归来定义。例如,自然数的加法函数可以定义为
_+_:自然->自然->自然零+米=米suc n+m=suc(n+m)
顺便说一下,我们注意到混合修复程序的形式_+_
运算符可以用于此类定义的左侧和右侧。
为了确保规范化,数据类型声明中定义的类型的归纳出现必须出现在严格的正位置。例如,不允许使用以下数据类型:
数据错误:设置位置坏:(坏->坏)->坏
因为出现了坏
在构造函数的参数中。
有关简单数据类型的更多信息.
参数化数据类型
数据类型可以取决于参数。例如,考虑以下声明:
数据列表(A:Set):设置位置[]:列表A_::_:A->列表A->列表A
这表明列表A
为类型的元素列表集A类
。由于定义是在类型上参数化的A类
,我们有效地定义了家庭类型的列表A
,每个一个A类
.
和往常一样,施工人员[]
(对于空列表)和_::_
(针对“cons”操作)。当这些构造函数稍后用作函数时,它们的类型被隐式量化A类
:
[]:{A:Set}->列表A_::_:{A:Set}->A->列表A->列表A
在数据类型声明中,参数写在数据类型名称之后,写在:
。参数的范围扩展到整个数据类型声明,因此它们的名称(例如A类
在上面的示例中)可以在构造函数声明中使用。
有关参数化数据类型的详细信息.
索引数据类型
数据类型也可以是编入索引的; 在这种情况下,它们也被称为归纳家庭. The difference between an指数和a参数是指索引在类型的整个定义中不必是常量。例如,对于自然数n个
,考虑类型IsEven n(偶数)
证明n个
是均匀的。这可以归纳为索引数据类型,如下所示:
data IsEven:Nat->设置位置evenZ:IsEven零evenSS:(n:Nat)->IsEven n->IsEver(suc(suc n))
注意,与参数不同A类
在上面的列表定义中,索引n个
在整个定义中不是恒定的。逻辑学家和理论计算机科学家可能会发现,将索引数据类型视为推理规则事实上,上述声明IsEven(平均值)
谓词在更传统的符号中与以下推理规则完全等价:
n:国家IsEven n------------ --------------------------IsEven 0 IsEven(n+2)
在数据类型声明中,索引显示在:
。索引的范围不会扩展到构造函数声明,并且索引可以在构造函数返回类型中采用任意值。
什么时候?模式匹配关于归纳族的一个元素,我们得到信息关于索引。区分由模式匹配确定的模式部分(无法访问的模式)和构成实际模式的部分匹配时,不可访问的模式以点作为前缀。例如,我们可以证明两个偶数之和也是偶数。
偶数+:(n m:Nat)->IsEven n->IsEver m->IsEvan(n+m)偶数+.0m偶数Z em=em偶数+。(suc(sucn))m(均匀SS n en)em=evenSS(n+m)(偶数+n m en em)
该证明是通过对以下证明的递归进行的n个
是均匀的。上的模式匹配这个证明将迫使n个
因此n个
是前缀为点,表示它们不是模式匹配的一部分。在这种情况下,我们可以n个
和米
隐式并将证明写为
偶数+:{nm:Nat}->IsEven n->IsEven m->IsEver(n+m)偶数+evenZ em=em偶数+(evenSS n en)em=evenSS _(偶数+en em)
有关入职家庭的更多信息.
结合参数和指标
数据类型声明可以同时包含参数和索引。例如,考虑以下Agda中常见的长度向量定义n个
包含来自的元素A类
:
数据Vec(A:设置):ℕ -> 设置位置[]:Vec A零_■_:A->Vec A n->Vec A(例如)
在这里,A类
是一个参数,出现在:
,而编号:ℕ
是一个索引,出现在:
.
感应递归类型
定义数据类型是可能的,有时也是必要的A类
和一个函数(f)
通过同时相互归纳/递归研究数据类型:定义f(x)
要求x:A
待定义,以及x:A
可能需要f(y)
已经为一些结构较小的元素定义y:答
这种结构在Agda中很容易实现,称为感应递归的类型。
对于一个(人为的)示例,考虑一个类型我的列表
自然数列表的属性是每个列表元素都大于其右侧所有列表元素的总和。建造师欺骗
接受三个参数:列表的头n个
,列表的尾部纳秒
以及一个证据n>和ns
。我们可以定义类型我的列表
和功能总和
通过相互归纳/递归同时进行:
data MyList:设置总和:MyList->Nat数据MyList,其中nil:我的列表缺点:(n:Nat)->(ns:我的列表)->(n>总和ns)->我的列表总和nil=零和(cons n ns _)=n+和ns
有关归纳递归类型的更多信息.
共性数据类型
TODO:添加信息。
有关共性数据类型的更多信息.
语法
数据声明包括:
数据类型声明的语法为:
data<name><parameters>:<indexs>其中<构造函数><构造函数>:<term>...
为了获得更大的灵活性(例如,允许相互递归定义),还可以将声明部分与定义部分分开。在这种情况下,声明部分的语法是:
数据<名称><参数>:<索引>
定义部分的语法为:
data<name><parameters>其中<构造函数><构造函数>:<term>...
语法部分如下:
<名称>
是新的不合格名称,声明的数据类型的名称。
<参数>
是可选的望远镜.这将为指定参数<名称>
在构造函数的类型上没有变化。中引入的变量<参数>
都在索引和所有构造线的范围内。
<指数>
是形式的一个术语<索引1>-><索引2>->…-><索引>-><宇宙>
,表示其最内层范围为宇宙.这将剩余参数指定给<名称>
以及结果类型(universe)。参数<索引1>
, ...,<索引>
被称为指数并且在构造函数的类型中不需要是常量。中引入的任何变量的范围<指数>
仅扩展到指数。
可能没有或更多<构造函数>
行。每个<构造函数>
是一个非限定名称。它不需要是新的;构造函数可能会重载。这个<术语>
构造函数后面是一个表示函数空间的术语,函数空间的最里面的范围是<名称>
.