我不知道为什么我的功能不起作用。我已经阅读了关于非详尽功能的所有帖子,但据我所知,我的功能可以满足所有可能的选项。
ascending :: [Int] -> Bool
ascending [] = error "Empty list given"
ascending [x] = True
ascending [x,y] | y>=x = True
| x<y = False
ascending (x:y:xs) | y>=x = (ascending (y:xs))
| x<y = False
结果:
*Main> ascending []
*** Exception: Empty list given
*Main> ascending [1]
True
*Main> ascending [1, 2]
True
*Main> ascending [2, 1]
*** Exception: test01.hs:(51,1)-(56,55): Non-exhaustive patterns in function ascending
它适用于一对,但如果该对不是提升则不适用。当我按照我的代码时,应该只返回False。
答案 0 :(得分:4)
仔细查看[x,y]
模式的警卫:
ascending [x,y] | y>=x = True
| x<y = False
当应用于[2,1]
时,会检查第一个警卫并评估为False
(因为2> = 1);然后,检查第二个警卫,但它也评估为False
(因为1&lt; 2)。因此,使用下一个模式(因为[2,1]
也匹配(x:y:ys)
),但完全相同的事情发生。因为这是最后一种模式,GHC正确地尖叫着你。
你的警卫中的不平等不是互补的。你的第三个模式应该是
ascending [x,y] | x <= y = True
| x > y = False
或者,为了留出更少的错误空间,
ascending [x,y] | x <= y = True
| otherwise = False
然而,仍有很大的改进空间。特别是:
Bool
,所以只使用guards来显式返回一个布尔值是多余的。考虑到所有这些,你可以简单地写一下
ascending :: [Int] -> Bool
ascending (x:y:xs) = x <= y && ascending (y:xs)
ascending _ = True
最后,您可以使用and
和zipWith
的组合来更多地压缩代码:
ascending :: [Int] -> Bool
ascending xs = and $ zipWith (<=) xs (tail xs)