Haskell如何实现删除列表首个满足谓词条件的元素
错误原因
- 拼写错误:递归分支的函数名多输入了一个
r,写成了rremoveFirst,导致removeFirst仅定义了空列表分支,模块加载失败,自然会在ghci中触发变量不在作用域的报错。 - 逻辑错误:判断条件写反,且找到第一个匹配元素后不需要继续递归,直接丢弃当前元素、保留后续所有元素即可。你现有代码的逻辑等价于过滤出所有不满足谓词的元素,和需求完全不符。
符合要求的一行实现
removeFirst :: [a] -> (a -> Bool) -> [a] removeFirst xs p = (\(a, b) -> a ++ drop 1 b) $ break p xs
实现说明
标准库的break函数会接收谓词和列表,返回(不满足谓词的最长前缀, 剩余后缀)二元组:
- 当存在满足谓词的元素时,后缀的第一个元素就是第一个匹配项,用
drop 1丢弃后拼接前缀即可得到结果 - 当没有满足谓词的元素时,后缀为空,
drop 1 []仍然返回空列表,最终结果和原列表一致,自动覆盖边界情况
测试验证
你给出的用例全部可以正常运行:
removeFirst "abab" (< 'b') -- 输出 "bab" removeFirst "abab" (== 'b') -- 输出 "aab" removeFirst "abab" (> 'b') -- 输出 "abab" removeFirst [1,2,3,4] even -- 输出 [1,3,4]
内容的提问来源于stack exchange,提问作者Mampenda
相关产品推荐
相关产品推荐

