英文:
Non-exhaustive patterns in function buildTree' Haskell
问题
我使用返回元组的函数。但当我尝试运行该函数时,它抛出一个异常:函数中存在非穷尽模式。
buildTree' :: String -> Tree -> (String, Tree)
buildTree' (x:xs) currenttree
    | null (x:xs) = ("empty", currenttree)
    | isDigit x && (take 1 xs == ['+'] || take 1 xs == ['-']) = buildTree' xs (Node [x] Empty Empty)
    | isDigit x = buildTree' newstring1 (snd (buildrecursion (getminiexpr (x:xs)) Empty))
    | elem x "+-" = buildTree' newstring (buildTree2 currenttree newtree [x])
        where newtree = snd (buildrecursion (getminiexpr xs) Empty)
              newstring = drop (length (getminiexpr xs)) xs
              newstring1 = drop (length (getminiexpr (x:xs))) (x:xs)
getminiexpr :: String -> String
getminiexpr input = takeWhile (\y -> y /= '+' && y /= '-') input
英文:
I use function that returns tuples. But when I try to run the function it gives me an exception: Non-exhaustive patterns in function.
buildTree' :: String -> Tree  -> (String,Tree)
buildTree' (x:xs)  currenttree 
|null (x:xs) = ("empty", currenttree)
|isDigit x && ( take 1  xs == ['+'] ||  take 1 xs == ['-'])= buildTree' xs (Node [x] Empty Empty)
|isDigit x = buildTree' newstring1 (snd (buildrecursion (getminiexpr(x:xs)) Empty))
|elem x "+-" = buildTree' newstring (buildTree2 currenttree newtree [x])
    where newtree = (snd (buildrecursion (getminiexpr xs) Empty))
          newstring = drop (length(getminiexpr xs)) xs
          newstring1 = drop (length(getminiexpr (x:xs))) (x:xs)
getminiexpr :: String -> String 
getminiexpr input = takeWhile ( \y -> y /= '+' && y /= '-') input
答案1
得分: 3
(x:xs) 不是一个任意的列表/字符串,它是一个非空的列表/字符串,其头部是 x,尾部是 xs。因此
buildTree' (x:xs) currenttree
   ...
只处理 非空 列表。使用 -Wall 编译会警告缺少空列表的情况。因此,你需要:
buildTree' [] currenttree = ...
buildTree' (x:xs) currenttree
   ...
根据你的代码,我们可以移除 null 守卫:
buildTree' [] currenttree = ("empty", currenttree)
buildTree' (x:xs) currenttree
   | isDigit x && (take 1 xs == ['+'] || take 1 xs == ['-']) = buildTree' xs (Node [x] Empty Empty)
   ...
类似地,take 检查需要不仅仅是列表的头部 x。你可以改写为:
buildTree' [] currenttree = ("empty", currenttree)
buildTree' (x1:x2:xs) currenttree
   | isDigit x1 && (x2 == '+' || x2 == '-') = buildTree' (x2:xs) (Node [x1] Empty Empty)
   ...
甚至可以这样写:
buildTree' [] currenttree = ("empty", currenttree)
buildTree' (x1:x2:xs) currenttree
   | isDigit x1 && (x2 `elem` "+-") = buildTree' (x2:xs) (Node [x1] Empty Empty)
   ...
我无法确定你的逻辑是否正确。
英文:
(x:xs) is not an arbitrary list/string, it is a non empty list/string whose head is x and whose tail is xs. Hence
buildTree' (x:xs)  currenttree 
   ...
only handles non empty lists. Compiling with -Wall would warn that the empty list case is missing. So, you need:
buildTree' [] currenttree = ...
buildTree' (x:xs)  currenttree 
   ...
Adapting your code, we can remove the null guard:
buildTree' [] currenttree = ("empty", currenttree)
buildTree' (x:xs)  currenttree 
   | isDigit x && ( take 1  xs == ['+'] ||  take 1 xs == ['-'])= buildTree' xs (Node [x] Empty Empty)
   ...
Similarly, the take checks need more than the head x of the list. You can write, instead:
buildTree' [] currenttree = ("empty", currenttree)
buildTree' (x1:x2:xs)  currenttree 
   | isDigit x1 && ( x2 == '+' || x2 == '-') = buildTree' (x2:xs) (Node [x1] Empty Empty)
   ...
or even
buildTree' [] currenttree = ("empty", currenttree)
buildTree' (x1:x2:xs)  currenttree 
   | isDigit x1 && (x2 `elem` "+-") = buildTree' (x2:xs) (Node [x1] Empty Empty)
   ...
I have no idea about whether your logic is correct.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论