我在用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)
答案 0 :(得分:3)
对于INode n left right
,您的目标是根据(++)
的使用来返回元素列表。但是类型仍然不匹配,因为n-1
是Int
而不是列表。
如果要减少树中的项目,则还应为每个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