Haskell中如何生成无重复二元子列表并添加筛选条件?
在Haskell中生成无序二元子列表并支持筛选
嘿,这个需求很实用,咱们一步步来实现它!核心要解决两个问题:一是生成不重复的无序二元子列表(比如[1,2]和[2,1]只保留一个),二是扩展支持自定义筛选条件。
第一步:生成基础的无序二元子列表
要避免逆序重复,关键逻辑是:只取列表中前面元素与后续元素的组合——也就是每个元素只和它之后的元素配对,从根源上杜绝[2,1]这种重复项。
这里有两种直观的实现方式:
方式1:递归实现(逻辑易懂)
这种写法适合新手理解递归的思路:
uniquePairs :: [a] -> [[a]] uniquePairs [] = [] -- 空列表没有任何子列表 uniquePairs (x:xs) = map (\y -> [x, y]) xs -- 把当前元素x和后面所有元素逐一配对 ++ uniquePairs xs -- 递归处理剩下的子列表
测试效果:
> uniquePairs [1,2,3] [[1,2],[1,3],[2,3]]
完全符合你的预期!
方式2:用tails的列表推导式(简洁优雅)
如果你偏爱更紧凑的代码,可以用Data.List模块里的tails函数(需要先导入import Data.List):
import Data.List (tails) uniquePairs :: [a] -> [[a]] uniquePairs xs = [[x, y] | (x:ys) <- tails xs, y <- ys]
tails [1,2,3]会生成[[1,2,3],[2,3],[3],[]],我们遍历每个非空的(x:ys),再从ys里取元素y,自然保证了x在y的前面,不会出现逆序重复对。
第二步:添加自定义筛选条件
接下来扩展函数,让它支持传入任意筛选规则。只需要在生成配对的过程中加入条件判断即可:
带筛选功能的版本
还是用列表推导式,保持代码简洁性:
import Data.List (tails) filteredUniquePairs :: (a -> a -> Bool) -> [a] -> [[a]] filteredUniquePairs cond xs = [[x, y] | (x:ys) <- tails xs, y <- ys, cond x y]
这里的cond是一个二元函数,用来判断配对(x,y)是否符合你的筛选要求。
测试筛选场景
比如你需要“子列表元素之和小于4”,就传入对应的条件函数:
> filteredUniquePairs (\x y -> x + y < 4) [1,2,3] [[1,2]]
完美得到你想要的结果!
如果有其他筛选需求,比如要求两个元素都是偶数,就可以传(\x y -> even x && even y),灵活性拉满。
内容的提问来源于stack exchange,提问作者Sawyer
相关产品推荐
相关产品推荐

