有什么办法可以解决缩进不正确的问题?我想检查给定树上的每个节点是否都大于其祖父(如果有)。 我编写了一个函数,该函数提供了每个级别上的所有节点,并且主要功能的想法是比较节点(如果它们小于其孙子节点)。
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”所在的整行中给出错误。
答案 0 :(得分:3)
通常最好使用模式匹配。通过使用模式匹配,如果您未涵盖所有可能的模式,则编译器会警告您,因此程序出错的可能性较小。
话虽这么说,您当前的尝试有很多问题,而不仅仅是缩进。
如果我们查看类型,您的grandchildrenIncreased
似乎没有多大意义。例如,您编写了grandchildrenIncreased Empty = Empty
,但是结果类型是Bool
,因此它应该是True
或False
。
您还可以将类型构造函数(如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
的情况下,我们检查子树l
和r
下的所有级别的值是否都大于v
,并且该条件也适用于l
和r
子树。
请注意,由于您构建了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