Non-exhaustive patterns in function `buildTree` Haskell

huangapple go评论91阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2020年1月3日 16:50:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/59575524.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定