如何模式匹配列表的末尾?
How to pattern match the end of a list?
假设我想删除列表末尾的所有零:
removeEndingZeros :: (Num a, Eq a) => [a] -> [a]
removeEndingZeros (xs ++ [0]) = removeEndingZeros xs
removeEndingZeros xs = xs
由于参数中的 (++)
运算符,这不起作用。如何通过模式匹配确定列表的结尾?
Data.List
中有一个函数可以做到这一点:
dropWhileEnd :: (a -> Bool) -> [a] -> [a]
dropWhileEnd p = foldr (\x xs -> if p x && null xs then [] else x : xs) []
因此您可以使用
删除尾随零
dropWhileEnd (== 0)
另一个非常相似的函数可以这样实现:
dropWhileEnd2 :: (a -> Bool) -> [a] -> [a]
dropWhileEnd2 p = foldr (\x xs -> if null xs && p x then [] else x : xs) []
dropWhileEnd2 p
与 reverse . dropWhile p . reverse
具有完全相同的语义,但可以合理地预期它会快一个常数因子。 dropWhileEnd
具有与其他不同的、不可比较的严格属性(它在某些方面更严格,而在其他方面则不那么严格)。
你能想出在什么情况下每个都可以更快吗?
假设我想删除列表末尾的所有零:
removeEndingZeros :: (Num a, Eq a) => [a] -> [a]
removeEndingZeros (xs ++ [0]) = removeEndingZeros xs
removeEndingZeros xs = xs
由于参数中的 (++)
运算符,这不起作用。如何通过模式匹配确定列表的结尾?
Data.List
中有一个函数可以做到这一点:
dropWhileEnd :: (a -> Bool) -> [a] -> [a]
dropWhileEnd p = foldr (\x xs -> if p x && null xs then [] else x : xs) []
因此您可以使用
删除尾随零dropWhileEnd (== 0)
另一个非常相似的函数可以这样实现:
dropWhileEnd2 :: (a -> Bool) -> [a] -> [a]
dropWhileEnd2 p = foldr (\x xs -> if null xs && p x then [] else x : xs) []
dropWhileEnd2 p
与 reverse . dropWhile p . reverse
具有完全相同的语义,但可以合理地预期它会快一个常数因子。 dropWhileEnd
具有与其他不同的、不可比较的严格属性(它在某些方面更严格,而在其他方面则不那么严格)。
你能想出在什么情况下每个都可以更快吗?