20-Recursive Types
引入
序列 List
、树 Tree
具有同样的特点:可能任意长短,但是结构简单并有规律
相比于将这几种数据类型区分开,我们选择将它们概括为一种基本形式,即归纳类型
利用变式类型和元组类型,我们尝试再次定义 List
如下:
NatList = <nil: Unit, cons: {Nat, NatList}>
引入一个递归操作符 μ
和一个元变量 X
NatList = μX . <nil: Unit, cons: {Nat, X}>
μ
代表为满足 X = <nil: Unit, cons: {Nat, X}>
实例
为了可以在上面提到的 List
上编程,我们需要:
-
常量
nil
,用来表示空列表 -
构造子
cons
,用来在列表头部添加元素 -
函数
isnil
,判断列表是否为空 -
提取表头的用于访问列表元素的函数
hd
和tl
根据上文提到的 NatList
的定义:
nil = <nil = unit> as NatList
cons = λn : Nat . λl : NatList . <cons = {n, l}> as NatList
isnil = λl : NatList . case l of
<nil = unit> -> false
| <cons = {n, l}> -> true
hd = λl : NatList . case l of <nil = unit> -> 0 | <cons = p> -> p.1
tl = λl : NatList . case l of <nil = unit> -> l | <cons = p> -> p.2
那么就可以写出一个求和函数:
sumlist = fix (λs : NatList -> Nat . λl : NatList . if isnil 1 then 0 else plus (hd l) (s(tl l)));
例子
-
饥饿函数
Hungry = μA . Nat -> A
-
流
Stream = μA . Unit -> {Nat, A}
-
计数器对象
Counter = μC . {get: Nat, inc: Unit -> C}
-
不动点构造子
fix = λf : T -> T . (λx : (μA . A -> T) . f(x x))(λx : (μA . A -> T) . f(x x))
通过对x
赋予一个递归类型解决了之前未能规范化的x x