映射在树中的列表

时间:2010-12-03 18:05:18

标签: haskell

我需要你的帮助来解决以下两个功能/问题:

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做一个初学者,所以不要生我的气。

由于

2 个答案:

答案 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)一样,您使用mapmtree2list应用于c中的每棵树。结果将是列表²。要将此列表列表转换为平面列表,您可以使用concat函数,该函数就是这样。


¹当然,除非你在列表树上调用mapmtree

²因为每个树都按mtree2listmap映射到列表,然后返回一个包含调用mtree2list的结果的列表。

答案 1 :(得分:2)

此外,第一部分是错误的,因为您的函数(a - &gt; a)没有为您提供所需的树类型。您需要将其更改为

mapmtree f (Leaf a) = Leaf (f a)