Haskell-使用列表的函数"Non-exhaustive patterns"错误



我试图在haskell中创建一个函数,以了解列表中的所有元素是否具有相同的长度。(我在以前的帖子中搜索过答案,但都不起作用)。

sameLength :: [[t]] -> String
sameLength [] = "Empty list"
sameLength [[items]]
    | and $ map (x -> length x == (length $ head [[items]])) [[items]] = "Same length"
    | otherwise = "Not the same length"

问题是它不起作用:

*Main> :l test.hs
[1 of 1] Compiling Main             ( test.hs, interpreted )
Ok, modules loaded: Main.
*Main> sameLength []
"Empty list"
*Main> sameLength [[1,2],[3,4]]
"*** Exception: test.hs:(2,1)-(5,39): Non-exhaustive patterns in function sameLength
*Main> sameLength [[1,2]]
"*** Exception: test.hs:(2,1)-(5,39): Non-exhaustive patterns in function sameLength

我真的不知道问题出在哪里。它处理参数是空列表而不是空列表的情况。我错了吗?我错过什么了吗?

感谢您的帮助:)

模式[x]与只包含一个项目x的列表匹配。因此,模式[[items]]与包含单个项目的单个列表相匹配。您想要的是在第二种情况下匹配所有非空列表。但由于空列表已经被匹配,通过消除,你只想匹配任何尚未匹配的列表。

sameLength :: [[t]] -> String
sameLength [] = "Empty list"
sameLength items = -- Code here

这里有太多[..]

sameLength [[items]] 

(Silvio解释得很好)-试试

sameLength items 

相反。

此外,作为a == a,你不必检查头部的长度是否与头部的长度相同(当然),所以我建议你这样做:

sameLength :: [[a]] -> Bool
sameLength []     = True
sameLength (h:tl) = all ((length h ==) . length) tl

因为我认为Bool的结果更有用,更自然

这是怎么回事

all接受一个谓词和一个列表,并检查该谓词是否适用于列表的每个元素-因此,作为谓词的(length h ==) . length = xs -> length h == length xs检查给定列表xs是否与头列表h具有相同的长度-因此,由于上面的注释,您只需使用尾列表tl 来检查

备注

你可以争论是否空列表的所有元素都应该有相同的长度,但我认为答案应该是肯定的;)

示例

Prelude> sameLength [[1,2],[3,4]]
True
Prelude> sameLength [[1,2],[3,4,5]]
False
Prelude> sameLength [[1,2]]
True
Prelude> sameLength []
True

以防你担心表现

(或者你不喜欢无积分的风格)

sameLength :: [[a]] -> Bool
sameLength []     = True
sameLength (h:tl) = let l = length h
                    in all (xs -> length xs == l) tl

相关内容

  • 没有找到相关文章

最新更新