1

所以我正在学习 Haskell,我必须实现一个 treeunzip 函数,该函数采用类型为 (Tree (a,b)) 的树,其中“a”和“b”是整数,并返回解压缩的两棵树的列表,即是(树 a,树 b)。

我可以得到两棵树中的一棵,但我不能将它们放在一个列表中。我想出的是:

treeunzip :: (NewTree) -> (treeunzipL, treeunzipR)

新树定义为:

data NewTree = NewLeaf | NewNode Int Int NewTree NewTree deriving Show

树定义为:

data Tree = Leaf | Node Int Tree Tree deriving Show

这是treeunzipL和treeunzipR函数,我不知道是否重要。

treeunzipL :: (NewTree) -> (Tree)
treeunzipL NewLeaf = (Leaf)
treeunzipL (NewNode x y lSubTree rSubTree) = (Node x (treeunzipL (lSubTree)) (treeunzipL (rSubTree)))


treeunzipR :: (NewTree) -> (Tree)
treeunzipR NewLeaf = (Leaf)
treeunzipR (NewNode x y lSubTree rSubTree) = (Node y (treeunzipR (lSubTree)) (treeunzipR (rSubTree)))

现在加载模块时显然给我一个错误,因为 treeunzip 有签名但没有实现。有没有办法解决这个问题?

谢谢你。

4

1 回答 1

2

您的问题似乎是您试图在类型中暗示定义。两者是分开的,必须单独提供。(编译器可以从定义中推断出类型,但不能从类型中推断出定义。)

treeunzip :: NewTree -> (Tree, Tree)
treeunzip t = (treeunzipL t, treeunzipR t)

但是,您应该将原始类型参数化为

data Tree a = Leaf | Node a (Tree a) (Tree a)

这样您只需要一个treeunzip功能:

treeunzip :: Tree (a, b) -> (Tree a, Tree b)
treeunzip Leaf = (Leaf, Leaf)
treeunzip (Node (a, b) left right) = ((Node a left' right'),
                                      (Node b left'' right''))
    where (left', left'') = treeunzip left
          (right', right'')  treeunzip right

> treeunzip (Node (1,2) (Node (3,4) Leaf Leaf) (Node (5,6) Leaf Leaf))
(Node 1 (Node 3 Leaf Leaf) (Node 5 Leaf Leaf),Node 2 (Node 4 Leaf Leaf) (Node 6 Leaf Leaf))
于 2016-10-21T14:25:14.333 回答