我正在学习Haskell并遇到了一些我不太了解的事情。我有以下递归数据类型:
data TList a = Tnil | Tcons (TList a) a
当我看到这个时,我理解为创建一个名为TList的数据类型,它具有泛型类型a。这有两个构造函数Tnil和Tcons。基本上我试图添加一个附加两个列表的函数,所以我编写了以下模式匹配函数:
tappend :: TList a -> TList a -> TList a
tappend (Tcons t h) y = Tcons h (tappend t y)
我在尝试运行它时遇到错误,说“无法匹配预期类型'TList(TList a)'与实际类型'a'”同样如果有人可以分解数据我创建的类型很棒。递归部分是我无法绕过它的东西。
答案 0 :(得分:4)
在你的定义中,有时会有点 uncommon :
data TList a = Tnil | Tcons (TList a) a
此处Tcons
的第一个参数为TList a
,后跟a
。因此,这意味着您可能首先指定init
(列表的第一部分),然后指定last
(最后一个元素)。通常,链接列表的定义方式相反:Tcons
首先有head
(a
)后跟tail
:TList a
包含列表的其余部分。
但是现在让我们使用上面的定义。让我们检查参数:
tappend :: TList a -> TList a -> TList a
tappend (Tcons t h) y = Tcons h (tappend t y)
在右侧,我们看到您构建了一个新的Tcons
,但作为第一个参数,您使用h
,这是a
,作为您使用的第二个参数{{1这将生成一个列表,因此您使用翻转参数调用构造函数。我们可以用以下方法解决:
tappend t y
但是现在我们仍然会收到错误,因为我们没有考虑到遇到tappend :: TList a -> TList a -> TList a
tappend (Tcons t h) y = Tcons (tappend t y) h
时我们应该做些什么,在这种情况下我们可以返回第二个列表:
Tnil
现在该函数将编译并运行。但结果有点奇怪。如果我们使用例如:
tappend :: TList a -> TList a -> TList a
tappend Tnil y = y
tappend (Tcons t h) y = Tcons (tappend t y) h
(当然我们不能使用列表语法),我们将输出:
tappend [1, 4, 2, 5] [1, 3, 0, 2]
所以事实上我们会以翻转的方式附加这些内容。我不太清楚你想要tappend [1, 3, 0, 2, 1, 4, 2, 5]
函数的语义。