使用Haskell sum类型来生成递归列表 - 递归锚点?

时间:2016-02-12 12:42:44

标签: haskell recursion

尝试更好地理解Haskell,我想使用sum类型构建一些递归列表结构。

这两种类型无关,但在同一文件中:

data EList = EList {elem::Point, rest::EList} | Empty
data ETree = ENode {val:: Int, left::ETree, right::ETree} | Empty

所以我得到了一个"空'""'''错误。阅读this帖子,我明白了这一点。不是关键字(正如我在课堂上呈现此数据类型时所假设的那样)。

如果我想在我的程序中使用这样的n种类型,我必须为空元素提出n个不同的名称,这看起来并不正确。

是否有一个共同的表达式来确定列表的结尾? 或者我应该不使用这个'自制'类型?

1 个答案:

答案 0 :(得分:2)

假设您被允许使用Empty构造函数声明两种数据类型,就像您所做的那样。鉴于定义

x = Empty

x的类型是什么?它可以是EListETree,但计算机无法知道您的意思。这就是为什么一般来说,您不能在给定文件中多次声明相同的名称。

一个简单的解决方案就是使用不同的名称。在这里,我使用Nil作为空列表,Leaf作为空树,这是常规的。

data List = Cons Point List | Nil
data Tree = Node Int Tree Tree | Leaf

(旁白:在sum类型中声明记录字段通常不是一个好主意,因为这意味着提取器将是部分函数。)

另一种方法是将两个重叠的名称放在不同的文件中。

List.hs:

module List where
data List = Cons Point List | Empty

Tree.hs:

module Tree where
data Tree = Node Int Tree Tree | Empty

现在,如果您导入这两个模块,则不允许引用Empty,因为机器再一次不知道您的意思。但这次,您可以使用合格的名称自行解决。

import List
import Tree

emptyList = List.Empty
emptyTree = Tree.Empty