我需要你的帮助来解决以下两个功能/问题:
1)
我必须替换树中的元素。树的分支可以有任意数量的子分支,如下面的代码所示。
data Tree a = Leaf a | Branch a [(Tree a)] deriving (Show)
mapmtree :: (a -> a) -> Tree a -> Tree a
mapmtree f (Leaf a) = (f a)
mapmtree f (Branch a c) = Branch (map f a) (mapmtree f c)
我必须浏览元素并进行更改。我的问题在最后一行。 mapmtree函数接受(树a)但是分支可以有一个子分支列表,因此不可能编译上面的代码,因为它给出了错误。如何在分支的子列表上调用mapmtree函数?
这是我加载时出现的错误:
Couldn't match expected type `Tree a'
against inferred type `[Tree a]'
In the second argument of `mapmtree', namely `c'
In the second argument of `Branch', namely `(mapmtree f c)'
In the expression: Branch (map f a) (mapmtree f c)
2)
第二个涉及将树变成深度优先中的列表这是我现在的代码,但我被困住了,不知道如何进一步:
data Tree a = Leaf a | Branch a [(Tree a)] deriving (Show)
mtree2list :: Tree a -> [a]
mtree2list (Leaf a) = [a]
mtree2list (Branch a c) = a : (mtree2list c)
还需要帮助以及如何实施它。与上述相同的问题,分支可以有许多子树,需要在深度优先中进行处理,以制作元素列表。
请在Haskell做一个初学者,所以不要生我的气。
由于
答案 0 :(得分:5)
<强> 1)强>
首先,我注意到你正在做map f a
虽然a
是单个值,而不是列表¹。所以你应该f a
而不是map f a
。
现在问你实际问的问题:
你是对的,它不起作用,因为c
是一个树列表而mapmtree
只想要一棵树。所以你会怎么做?您将mapmtree
应用于树列表中的每个树,然后使用结果树列表作为新分支的树列表。你是怎样做的?在列表中使用map
:
mapmtree f (Branch a c) = Branch (f a) (map (mapmtree f) c)
<强> 2)强>
与1)一样,您使用map
将mtree2list
应用于c
中的每棵树。结果将是列表²。要将此列表列表转换为平面列表,您可以使用concat
函数,该函数就是这样。
¹当然,除非你在列表树上调用mapmtree
。
²因为每个树都按mtree2list
和map
映射到列表,然后返回一个包含调用mtree2list
的结果的列表。
答案 1 :(得分:2)
此外,第一部分是错误的,因为您的函数(a - &gt; a)没有为您提供所需的树类型。您需要将其更改为
mapmtree f (Leaf a) = Leaf (f a)