递归数据类型 |
|
假设您想表示一个带有标记节点和编号叶子的树。
要构建这样的数据结构,您需要为每个节点变体创建一个构造函数:InteriorNode
和 LeafNode
。在遍历数据结构时,您需要一个 switch 语句来对不同的数据执行不同的操作。函数 deftype
[3] 从简单的规范中创建构造函数。函数 cases
返回一个切换函数,可用于遍历数据结构。
require'DefType' deftype 'bintree' { 'number'; Node = { name ='string', left ='bintree', right='bintree', }; } local function node(name, left, right) return Node{name=name, left=left, right=right} end local tree = node( 'cow', node('rat', 1, 2), node('pig', node('dog', 3, 4), 5) ) ------------------------------------------------------------------------------ local leafsum leafsum = cases 'bintree' { number = function(n) return n end; Node = function(node) return leafsum(node.left) + leafsum(node.right) end; } io.write('leaf sum = ', leafsum(tree), '\n\n') ------------------------------------------------------------------------------ local function indented(level, ...) io.write(string.rep(' ', level), unpack(arg)) end local treewalki treewalki = cases 'bintree' { number = function(n) io.write(' @LeafNode ', n, '\n') end; Node = function(node, level) local plus1 = level+1 io.write(' {\n') indented(plus1, '@InteriorNode ', node.name, '\n') indented(plus1, '@left') treewalki(node.left, plus1) indented(plus1, '@right') treewalki(node.right, plus1) indented(level, '}\n') end; } local function treewalk(t) io.write('@Tree') treewalki(t, 0) end treewalk(tree)
leaf sum = 15 @Tree { @InteriorNode cow @left { @InteriorNode rat @left @LeafNode 1 @right @LeafNode 2 } @right { @InteriorNode pig @left { @InteriorNode dog @left @LeafNode 3 @right @LeafNode 4 } @right @LeafNode 5 } }
树形图由 Lout[2] 从 [fig1.lt] 生成。Ghostscript 用于将 EPS 转换为 JPG。