在Haskell中遍历一棵树?

时间:2020-05-05 21:51:22

标签: haskell

我在用haskell编写函数时遇到了麻烦,该函数会生成其参数的副本,其中每个节点的值都减小了1。我的主要问题是,鉴于此问题,如何在haskell中进行递归遍历。这是我给的:

data ITree = IEmpty
              | INode Int ITree ITree   
    deriving (Eq, Show)

-- An example of a tree
t1 :: ITree
t1 = INode 2 (INode 1 (INode 4 IEmpty IEmpty)
                      (INode 5 IEmpty IEmpty))
             (INode 7 IEmpty IEmpty) 

在这里尝试:

decITree :: ITree -> ITree
decITree IEmpty = undefined
decITree (INode n left right) = (n-1) ++ (decITree left) ++ (decITree right)

1 个答案:

答案 0 :(得分:3)

对于INode n left right,您的目标是根据(++)的使用来返回元素列表。但是类型仍然不匹配,因为n-1Int而不是列表。

如果要减少树中的项目,则还应为每个ITree 返回和一个ITree。因此骨架应如下所示:

decITree :: ITree -> ITree
decITree IEmpty = … -- (some ITree)
decITree (INode n left right) = … -- (some ITree)

对于IEmpty,只有一个有意义的值要返回:IEmpty也是如此,因为没有什么可减少的。

对于INode,我们可以返回一个INode with a decremented value(n-1)作为值,我们需要递归该节点的子节点:

decITree :: ITree -> ITree
decITree IEmpty = IEmpty
decITree (INode n left right) = INode (n-1) (decITree left) (decITree right)

上面是映射的一种特殊类型。通常,最好使用更通用的功能。例如,我们可以定义一个abstract data type [haskell-wiki],通过使用DeriveFunctor extension,我们可以让编译器为我们完成工作:

{-# LANGUAGE DeriveFunctor #-}

data Tree a = Empty
             | Node a (Tree a) (Tree a)
    deriving (Eq, Show, Functor)

然后递减树的元素就是:

decTree :: Tree Int -> Tree Int
decTree = fmap pred