Haskell-函数中使用数据类型的非穷举模式

Haskell-函数中使用数据类型的非穷举模式,haskell,recursion,types,Haskell,Recursion,Types,我试图在Haskell wiki上解决这个问题:(问题12) 我的解决办法如下: data Repeats a = Single a | Multiple Int a deriving Show encodelens :: Eq a => [a] -> [Repeats a] encodelens xs = foldr (\x acc -> case acc of [] -> [Single x]

我试图在Haskell wiki上解决这个问题:(问题12)

我的解决办法如下:

data Repeats a = Single a | Multiple Int a deriving Show

encodelens :: Eq a => [a] -> [Repeats a]
encodelens xs = foldr (\x acc -> case acc of
                                  [] -> [Single x]
                                  (l:ls) -> case l of
                                             (Single x') -> if x == x'
                                                             then [(Multiple 2 x)] ++ ls
                                                             else [(Single x)] ++ (l:ls)
                                             (Multiple c x') -> if x == x'
                                                                 then [(Multiple (c+1) x)] ++ ls
                                                                 else [(Single x)] ++ (l:ls)
                      ) [] xs

decodelens :: Eq a => [Repeats a] -> [a]
decodelens [] = []
deocdelens (r:rs) = case r of
                     (Single x) -> [x] ++ decodelens rs
                     (Multiple c x) -> take c (repeat x) ++ decodelens rs
decodelens
不工作,故障原因如下:

decodelens [Multiple 4 'a',Multiple 2 'b',Multiple 2 'c',Multiple 2 'd',Single 'e',Multiple 3 'f']

"*** Exception: encode-len-with-cardinality.hs:(17,1)-(19,47): Non-exhaustive patterns in function decodelens
我不确定它是如何无法匹配模式的

更新:


正如下面的注释所指出的,错误在于第二个模式匹配的函数名
deocdelens
。我想知道有没有办法避免这种错误?

这确实是一种很难抓住的错误类型。请注意,如果您在签名或
decodelens
的第一个图案上有打字错误,GHC会投诉,因为签名必须与函数定义“相邻”


我想你在这里能做的最好的事情就是打开
-Wmissing signatures
。对于上面的代码,这将触发关于顶级函数
deocdelens
没有签名的警告。当然,这意味着您必须为所有顶级函数显式地编写签名,但通常还是鼓励这样做。

不管Haskell和其他语言如何,防止这种问题的一个方法是养成一种习惯,永远不要用三个以上的字母键入名称(除了第一次写的时候,通常是为了签名)。这就是自动完成的目的


当然,这也有其自身的问题——我不止一次发现自己第一次键入的名称错误,然后自动完成“粘贴”它贯穿我的程序。这样就可以很好地工作,只是在阅读代码时有点尴尬…

看看函数名的拼写:deocde vs.decode.dam,这么简单的错误。有没有办法避免这样的错误?我们都会犯这样的错误,这就是为什么ghc是一个很好的配对编程伙伴。@Ngm是的,有办法--使用
-Wall
打开警告!GHC应该警告您1)非穷举匹配和2)函数
deocde
开始定义时没有类型注释
deocde::…
。第二个应该指出问题。