查找并返回植根于Haskell中该节点的子树的高度

时间:2019-10-24 22:37:34

标签: haskell

data Tree a = Tip | Bin (Tree a) a (Tree a) deriving (Show, Eq)

我需要返回一棵形状与它的参数相同的树,但是每个节点标签都替换为第二个字段中包含原始标签的对。第一个字段应该是根于该节点的子树的高度。 这是我写的:

heights :: Tree a -> Tree (Integer, a)

heights Tip = Tip
heights (Bin Tip x Tip) = Bin Tip (1,x) Tip
heights (Bin l x r) = heights (Bin (heights l) (1 + max(heights l)(heights r)) (heights r))

我的代码有错误:

Couldn't match type `a' with `(Integer, a)'
      `a' is a rigid type variable bound by
          the type signature for heights :: Tree a -> Tree (Integer, a)
          at Project2.hs:47:12
    Expected type: Tree a
      Actual type: Tree (Integer, a)
    In the return type of a call of `heights'
    In the first argument of `Bin', namely `(heights l)'
    In the first argument of `heights', namely
      `(Bin (heights l) ((1 + max (heights l) (heights r))) (heights r))'

1 个答案:

答案 0 :(得分:1)

问题是您正试图从递归调用中提取高度信息。从原则上讲,这是一种好方法,但是问题是heights会返回整棵树,而不仅仅是给定树的高度。但是,您可以轻松地从中提取 高度:

extractPrecomputedHeight :: Tree (Integer, a) -> Integer
extractPrecomputedHeight Tip = 1
extractPrecomputedHeight (Bin _ (h,_) _) = h

然后,仅使用它来测量子树。最好只在每个{em> 中使用where绑定:

heights (Bin l x r) = Bin _ _ _
 where [l', r'] = heights <$> [l,r]
       h = 1 + max (extractPrecomputedHeight l') (extractPrecomputedHeight r')

填写_之间的差距。 (GHC可以为您提供帮助:它将在每个_上显示,在那里显示期望的类型,以及可用的本地绑定具有什么类型,因此很容易找到正确的定义。)