功能中的非详尽模式。创建玫瑰树 Haskell

Non-exhaustive patterns in function. Creating rose tree Haskell

我正在尝试编写一个函数,将玫瑰树列表与它们的父节点结合起来,父节点是给定玫瑰树根节点的最大值。例如;

RosesToRose [Rose 1 [Rose 1 [], Rose 2 []], Rose 3 [], Rose 4 [Rose 10 []]]

应该returnRose 4 [Rose 1 [Rose 1 [], Rose 2 []], Rose 3 [], Rose 4 [Rose 10 []]]

我收到错误“rosesToRose 函数中的非详尽模式”,我不确定是什么原因造成的。尝试匹配空列表作为输入并得到相同的错误。任何建议,将不胜感激。

我的代码:

data Rose a = Rose a [Rose a]
    deriving Show

rosesToRose:: (Ord a, Num a )=> [Rose a] -> Rose a
rosesToRose [(Rose node tree)] = Rose (maxRoseNode [(Rose node tree)]) [(Rose node tree)]

maxRoseNode:: (Ord a,Num a) =>[Rose a] -> a
maxRoseNode trs = case trs of
    [] -> 0
    (Rose node tree):xs -> maximum  ([maxRoseNode xs] ++ [node])

您使用的模式将只匹配 恰好 一个元素的列表。确实是模式:

rosesToRose <b>[(Rose node tree)]</b> = …

匹配列表 one Rose object。但是在您的示例数据中,您向它传递了一个包含三个元素的列表。此外,如果您传递具有一个元素的相同列表,maxRoseNode 没有多大意义。

你可以解决这个问题,只需将它与一个变量匹配(例如rs),然后构造一个RosemaxRoseNode rs作为值,rs 作为 children:

rosesToRose :: (Ord a, Num a) => [Rose a] -> Rose a
rosesToRose <b>rs</b> = Rose (maxRoseNode <b>rs</b>) <b>rs</b>

您可以通过首先检查它是否为空列表来提高 maxRoseNode 的可读性(和效率),如果不是,则计算 Rose 中包含的项目的最大值:

maxRoseNode:: (Ord a, Num a) => [Rose a] -> a
maxRoseNode [] = 0
maxRoseNode xs = maximum (map <b>(\(Rose x _) -> x)</b> xs)

此处 \(Rose x _) -> x 是一个 lambda 表达式,它将 Rose x _ object 映射到 x.

例如:

Prelude> rosesToRose [Rose 1 [Rose 1 [], Rose 2 []], Rose 3 [], Rose 4 [Rose 10 []]]
Rose 4 [Rose 1 [Rose 1 [],Rose 2 []],Rose 3 [],Rose 4 [Rose 10 []]]