Haskell函数求教:向嵌套列表各子列表依次添加元素的优雅实现
推荐实现方式
1. 递归实现(最简洁易读,惰性友好)
这是最符合函数式编程思维的实现,不需要依赖额外库,也避免了显式索引操作,对无限嵌套列表也能正常工作:
f :: a -> [[a]] -> [[[a]]] f _ [] = [] f e (cur:rest) = (e:cur : rest) : map (cur:) (f e rest)
逻辑说明:
- 基准情况:空输入列表返回空结果
- 每次处理第一个子列表
cur:- 直接给
cur头部加元素e,拼接后面的rest,得到第一个结果 - 递归处理后面的
rest列表,给递归生成的每个结果前面都拼接当前不变的cur,得到剩下的所有情况
- 直接给
2. 高阶函数组合实现(语义清晰)
借助Data.List的inits和tails工具函数,逻辑更直白:
import Data.List (inits, tails) f :: a -> [[a]] -> [[[a]]] f e xss = zipWith (\prefix (cur:suffix) -> prefix ++ (e:cur) : suffix) (inits xss) (tails xss)
逻辑说明:
inits xss获取所有前缀列表,tails xss获取所有后缀列表- 逐对拼接前缀、加了
e的当前子列表、后缀,得到每一种修改后的结果
优势对比你原有实现:
- 避免了显式索引比对和
length计算,不会在处理无限列表时卡住 - 没有边界条件隐患,不需要处理索引越界问题
- 代码语义更清晰,可读性更高
内容的提问来源于stack exchange,提问作者Evg
相关产品推荐
相关产品推荐

