在Haskell树中查找节点的值

时间:2014-03-29 20:41:38

标签: haskell tree algebraic-data-types

我目前正在搞乱一些Haskell树。我是Haskell的新手(来自C),我想知道如何从树中找到一个Node(我一直称之为叶子)的单个值。 如果我的树说:     (root)power,(branchLeft)2,(branchRight)3

如果我想读这个,2是3的力量,我应该怎么做呢? 我从零开始,在过去的3个小时里一直在搞乱代码而且还没有走得太远。

任何提示/想法?

2 个答案:

答案 0 :(得分:4)

您可以使用代数数据类型在内部节点中使用二元运算符对二叉树进行建模:

data Tree a = Leaf a | InnerNode (a -> a -> a) (Tree a) (Tree a) 

函数a -> a -> a是二元运算符。例如,一个简单的整数树可以定义为

tree :: Tree Integer
tree = InnerNode (+) (InnerNode (^) (Leaf 3) (Leaf 2)) (Leaf 5)

以您描述的方式评估或解释树可以编写函数

interpretTree :: Tree Integer -> Integer

要编写该函数,您可能希望使用模式匹配和递归:

interpretTree (Leaf x) = x           -- the base case
interpretTree (InnerNode f l r) = ...  -- use recursion here 

对于第二种情况,您可以递归计算子树的结果,并使用函数f将它们组合起来。

答案 1 :(得分:1)

我将按照您提到的行定义数据类型:

data Tree2 b a = Leaf a | Node b (Tree2 b a) (Tree2 b a)
  deriving Show

所以我可以使用

example :: Tree2 (Integer -> Integer -> Integer) Integer 
example = Node (^) (Leaf 2) (Leaf 3)

您可以在此类型上进行的最常见的折叠函数(“catamorphism”)是一个使用函数({{1})递归替换每个构造函数(LeafNode)的结构的函数。 },foldLeaf):

foldNode

所以我们应该能够使用它来定义很多函数,但特别是你要求的评估函数是

foldTree2 :: (a -> v) -> (b -> v -> v -> v) -> Tree2 b a -> v
foldTree2 foldLeaf foldNode = fold where 
   fold (Leaf a) = foldLeaf a
   fold (Node b left right) 
                 = foldNode b (fold left) (fold right)
 
inOrderApply :: Tree2 (a -> a -> a) a -> a
inOrderApply = foldTree2 id id