如何调整“尾部”以避免在Haskell中出现不正确的缩进

时间:2019-05-24 15:03:22

标签: haskell

有什么办法可以解决缩进不正确的问题?我想检查给定树上的每个节点是否都大于其祖父(如果有)。 我编写了一个函数,该函数提供了每个级别上的所有节点,并且主要功能的想法是比较节点(如果它们小于其孙子节点)。

data BTree = Empty | Node Int BTree Btree

grandchildrenIncreased :: BTree -> Bool
grandchildrenIncreased Empty = Empty
grandchildrenIncreased BTree = func BTree level
 where f BT n
  | head (level BT n) < head (level BT n+2) = tail (level BT 1)
     (level BT n+2) grandchildrenIncreased f BT (n+1)
  | length (level BT n) == 0 = True
  | otherwise = False

level :: BTree -> Int -> [a]
level Empty _ = []
level (Node n lt rt) 1 = [n]
level (Node _ lt rt) k
 = (level lt (k-1)) ++ (level rt (k-1))

它在“ tail”所在的整行中给出错误。

1 个答案:

答案 0 :(得分:3)

通常最好使用模式匹配。通过使用模式匹配,如果您未涵盖所有可能的模式,则编译器会警告您,因此程序出错的可能性较小。

话虽这么说,您当前的尝试有很多问题,而不仅仅是缩进。

如果我们查看类型,您的grandchildrenIncreased似乎没有多大意义。例如,您编写了grandchildrenIncreased Empty = Empty,但是结果类型是Bool,因此它应该是TrueFalse

您还可以将类型构造函数(如BTree)与数据构造函数混合使用。例如,第二行grandchildrenIncreased BTree = func BTree level也没有多大意义,因为BTree是一种类型,因此它不是树 values 的特定模式。

您似乎还使用level中的grandchildrenIncreased来引用level :: BTree -> Int -> [a]函数以及一些不存在的Int值。

最后,通过首先将树转换为级别列表,您失去了哪个节点连接到哪个祖父母的结构,从而难以检查。

grandchildrenIncreased :: BTree -> Bool
grandchildrenIncreased Empty = True
grandchildrenIncreased n@(Node v l r) =
    all (v <) (level n 3) && grandchildrenIncreased l && grandchildrenIncreased r

因此,在Node v l r的情况下,我们检查子树lr下的所有级别的值是否都大于v,并且该条件也适用于lr子树。

请注意,由于您构建了Int的树,因此level的最通用类型签名是:

level :: BTree -> Int -> [Int]
level Empty _ = []
level (Node n lt rt) 1 = [n]
level (Node _ lt rt) k = (level lt (k-1)) ++ (level rt (k-1))

但是,在这里定义children函数可能会更有用:

children :: BTree -> [BTree]
children Empty = []
children (Node _ lt rt) = [lt, rt]

以及提取Node的值的方法:

treeVal :: BTree -> Maybe Int
treeVal Empty = Nothing
treeVal (Node v _ _) = Just v

然后我们可以使用以下方法导出值:

import Data.Maybe(catMaybes)

grandchildrenIncreased :: BTree -> Bool
grandchildrenIncreased Empty = True
grandchildrenIncreased n@(Node v l r) =
    all (v <) (catMaybes (treeVal <$> (children n >>= children))) &&
    grandchildrenIncreased l && grandchildrenIncreased r