我刚刚开始学习Haskell,并为任何函数编写了自定义代码。 请建议为什么即使我使用了其他方式或出错的地方,它仍然显示非详尽模式错误?
提出的例外情况:- 异常:main.hs:(37,1(-(40,21(:函数myAny中的非穷举模式
myAny :: (a -> Bool) -> [a] -> Bool
myAny f (x:xs)
| f x == True = True
| f x == False = myAny f xs
| otherwise = False
您忘了为空列表实现子句。由于您执行递归,如果没有任何元素匹配,它最终将使用空列表调用myAny
。在这种情况下,您需要返回False
:
myAny :: (a -> Bool) -> [a] -> Bool
myAny _ [] = False
myAny f (x:xs)
| f x == True = True
| f x == False = myAny f xs
| otherwise = False
请注意,用f x
执行两次检查是没有意义的,如果它不是True
,它是False
的,所以otherwise
的情况通常永远不会发生:
myAny :: (a -> Bool) -> [a] -> Bool
myAny _ [] = False
myAny f (x:xs)
| f x = True
| otherwise = myAny f xs
我们可以通过(||) :: Bool -> Bool -> Bool
进一步简化此操作:
myAny :: (a -> Bool) -> [a] -> Bool
myAny _ [] = False
myAny f (x:xs) =f x ||myAny f xs
或使用foldr
模式:
myAny :: Foldable f => (a -> Bool) -> f a -> Bool
myAny f = foldr ((||) . f) False
这里的问题是Haskell不能将[]
解构为(x:xs)
,导致空列表未被覆盖的情况。
解决方案是指定:
myAny :: (a -> Bool) -> [a] -> Bool
myAny f (x:xs)
-- ...
myAny f [] = False