Haskell - "Non-exhaustive patterns" 使用列表的函数出错
Haskell - "Non-exhaustive patterns" error with a function using list
我正在尝试在 haskell 中创建一个函数来了解列表列表中的所有元素是否具有相同的长度。 (我在以前的帖子中搜索过答案,但 none 有效)。
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
是否具有与 head-list 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
我正在尝试在 haskell 中创建一个函数来了解列表列表中的所有元素是否具有相同的长度。 (我在以前的帖子中搜索过答案,但 none 有效)。
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
是否具有与 head-list 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