我在编写这个接受谓词和整数列表的函数时遇到问题,然后消除列表中最后一次出现的满足谓词的整数。我能够使用下面的函数取出列表中第一次出现的谓词:
fun :: (Int -> Bool) -> [Int] -> [Int]
fun check (s:ss)
|check s = ss
|otherwise = s : fun check ss
我需要帮助的是我应该如何修改此函数以取出最后一次出现的整数,而不是第一次出现的整数。例如,fun (<2) [3,4,1,5,0,-3,9]
会返回 [3,4,1,5,0,9]
.
最佳答案
(由于某些缩进问题,我无法使用 where
)
removeLast :: (a -> Bool) -> [a] -> [a]
removeLast p xs =
let
go c [] = tail (c [])
go c (x:xs)
| p x = c (go (x:) xs)
| otherwise = go (c . (x:)) xs
in case break p xs of
(ok, []) -> ok
(ok, x:xs) -> ok ++ go (x:) xs
go
收集谓词不包含在差异列表中的元素,并在找到满足谓词的新元素后将此列表添加到结果中。 break p xs
上的模式匹配可确保差异列表始终以满足谓词的元素开头,如果它是最后一个,我们可以将其删除。
适用于无限列表:
main = do
print $ removeLast (< 2) [3,4,1,5,0,-3,9] -- [3,4,1,5,0,9]
print $ removeLast (== 2) [1,3] -- [1,3]
print $ take 10 $ removeLast (< 2) (cycle [1,3]) -- [1,3,1,3,1,3,1,3,1,3]
这是一个混淆版本:
removeLast :: (a -> Bool) -> [a] -> [a]
removeLast p xs = case break p xs of
(ok, []) -> ok
(ok, x:xs) -> ok ++ foldr step (tail . ($[])) xs (x:) where
step x r c = if p x then c (r (x:)) else r (c . (x:))
关于list - 在 Haskell 中取出列表中某个元素的最后一次出现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33685051/