lanf Asked: 2024-10-11 08:11:26 +0800 CST2024-10-11 08:11:26 +0800 CST 2024-10-11 08:11:26 +0800 CST 在 Haskell 中,获取列表中的元素,包括满足某些谓词的第一个值 772 给定一个谓词p,takeWhile p xs给出满足的元素的最长前缀p。如何获取包含满足的元素的最短前缀p? 编辑:对于那些反对我的问题的人,如果你们能留下评论解释一下你们不喜欢什么,我会很高兴。 list 2 个回答 Voted Best Answer Ry- 2024-10-11T09:43:19+08:002024-10-11T09:43:19+08:00 break在第一次匹配时拆分列表,这似乎是一个很好的起点: cutAfter :: (a -> Bool) -> [a] -> Maybe [a] cutAfter p xs = case break p xs of (start, mid : _) -> Just (start ++ [mid]) _ -> Nothing 希望将不包含匹配元素的列表完整地取出似乎也是一个合理的选择: cutAfter :: (a -> Bool) -> [a] -> [a] cutAfter p xs = let (start, end) = break p xs in start ++ take 1 end 这个选项很好,因为它更高效、更懒惰——在使用列表之前不需要找到匹配项。 willeM_ Van Onsem 2024-10-11T15:10:13+08:002024-10-11T15:10:13+08:00 我们可以使用显式递归: cutAfter :: (a -> Bool) -> [a] -> [a] cutAfter p = go where go [] = [] go (x : xs) | p x = [x] | otherwise = x : go xs 如果列表不包含任何满足谓词的元素p,它将返回整个列表。因此,它只是不断产生元素,直到(并包括)第一个满足谓词的元素。 这也可以通过 foldr-pattern 来完成: cutAfter :: (a -> Bool) -> [a] -> [a] cutAfter p = foldr (\x -> if p x then const [x] else (x :)) []
break
在第一次匹配时拆分列表,这似乎是一个很好的起点:希望将不包含匹配元素的列表完整地取出似乎也是一个合理的选择:
这个选项很好,因为它更高效、更懒惰——在使用列表之前不需要找到匹配项。
我们可以使用显式递归:
如果列表不包含任何满足谓词的元素
p
,它将返回整个列表。因此,它只是不断产生元素,直到(并包括)第一个满足谓词的元素。这也可以通过 foldr-pattern 来完成: