如何在Haskell中实现不使用takeWhile的连续首元素匹配函数?
实现提取列表开头连续匹配元素的Haskell函数
递归实现
先给出最直观的递归写法,完全贴合需求:
f :: Eq a => a -> [a] -> [a] f _ [] = [] f a (x:xs) | x == a = x : f a xs | otherwise = []
逻辑非常直白:
- 空列表直接返回空
- 当第一个元素和
a相等时,把它加入结果,继续递归处理剩余列表 - 遇到不相等的元素时直接返回空列表——这就是递归的终止点,后面的元素不会再被处理,递归自然停止
更简洁的标准库实现
如果觉得递归不够简洁,Haskell标准库的takeWhile函数正好能完成这个任务,一行就能搞定:
f :: Eq a => a -> [a] -> [a] f a = takeWhile (== a)
takeWhile的作用就是遍历列表,只保留开头连续满足条件的元素,一旦碰到第一个不满足的元素就立刻停止,完美匹配你的需求。
和提取所有匹配元素的区别
你提到能实现提取所有a的函数,对比两者就能明确差异:
- 提取所有
a的函数,不管当前元素是否匹配,都会递归处理剩余列表,最终收集所有符合条件的元素 - 而我们这个函数,只要遇到第一个不匹配的元素就终止递归,完全忽略后续内容,因此只取开头连续的匹配部分
用你的例子验证:f 1 [1,1,2,2,1]会在碰到2时停止,返回[1,1];而提取所有的函数会继续处理后面的1,得到[1,1,1]。
内容的提问来源于stack exchange,提问作者lafinur
相关产品推荐
相关产品推荐

