Haskell玫瑰树合并函数非穷尽模式错误排查求助
Hey there! Let's break down why you're hitting that "Non-exhaustive patterns" error and fix your code to meet your requirements.
First, the Root Cause of the Error
Your rosesToRose function only defines a pattern for single-element lists ([(Rose node tree)]). It has no handling for empty lists or lists with multiple rose trees—so whenever you pass anything other than a single rose tree, Haskell can't find a matching pattern and throws the error.
On top of that, your maxRoseNode function has two issues:
- Returning
0for empty lists will give wrong results if all your rose tree roots are negative. - Recursively traversing subtrees is unnecessary—your requirement only asks for the maximum of the root nodes of the input list, not all nodes in the entire tree hierarchy.
Corrected Code
Let's rewrite the functions to fix these problems:
First, define a helper to get the maximum root from a list of rose trees:
-- Extracts all root nodes from the input list and returns their maximum maxRoseRoots :: Ord a => [Rose a] -> a maxRoseRoots = maximum . map (\(Rose root _) -> root)
Then fix rosesToRose to cover all input cases:
data Rose a = Rose a [Rose a] deriving Show rosesToRose :: (Ord a, Num a) => [Rose a] -> Rose a -- Handle empty list: Return a default rose tree (adjust this based on your needs) rosesToRose [] = Rose 0 [] -- Handle non-empty lists: Use max root as new parent, keep original list as subtrees rosesToRose roseList = Rose (maxRoseRoots roseList) roseList
Test Your Example
Let's run your sample input to verify:
testInput = [Rose 1 [Rose 1 [], Rose 2 []], Rose 3 [], Rose 4 [Rose 10 []]] rosesToRose testInput
Output:
Rose 4 [Rose 1 [Rose 1 [],Rose 2 []],Rose 3 [],Rose 4 [Rose 10 []]]
Perfect—this matches exactly what you expected!
Optional: More Strict Handling for Empty Lists
If you want to enforce that the input list can't be empty (instead of returning a default tree), you can use Maybe to make the function safer:
rosesToRose :: Ord a => [Rose a] -> Maybe (Rose a) rosesToRose [] = Nothing rosesToRose roseList = Just $ Rose (maxRoseRoots roseList) roseList
Key Takeaways
- Always make sure your pattern matches cover all possible input cases (empty, single, multiple elements).
- Keep helper functions focused—only compute what you need (in this case, just the roots of the input trees, not their subtrees).
- Avoid hardcoding default values like
0for edge cases; use types likeMaybeto make invalid states explicit.
内容的提问来源于stack exchange,提问作者anon0987654321

