F#实现纯函数惰性序列元素索引装饰的更简单方案?
最优解决方案
F#核心库已经内置了满足所有要求的原生API:Seq.mapi,它可以在遍历序列的同时传入元素对应的索引,本身是惰性求值的纯函数实现,无需手动编写复杂的Seq.unfold逻辑。
你需要的decorate函数可以一行实现:
let decorate = Seq.mapi (fun index item -> (item, index))
方案验证
Seq.mapi完全匹配两个核心要求:
- 惰性求值:只有迭代到序列的对应元素时才会执行映射逻辑,适配REST服务的按需拉取场景,不会提前全量加载数据
- 纯函数实现:内部状态由库封装,无任何对外暴露的可变变量,符合函数式编程规范
完整测试代码(保留调试日志)
let nums = seq { // 加入调试日志 let getN n = printfn "get: %d" n n getN 9; getN 12; getN 4; getN 17; getN 9; getN 7; getN 13 } let decorate = Seq.mapi (fun index item -> (item, index)) nums |> Seq.cache |> decorate |> Seq.iter (fun (n,index) -> printfn "ITEM %d: %d" index n)
执行后输出和预期完全一致,日志也会验证只有迭代到对应元素时才会触发getN调用,满足惰性要求。
原有方案说明
你自己用Seq.unfold实现的版本逻辑完全正确,也满足所有要求,只是Seq.mapi是标准库对这类通用场景的封装,不需要手动维护索引和剩余序列的状态,代码更简洁易维护,性能也经过官方优化。
内容的提问来源于stack exchange,提问作者Stephen Hosking
相关产品推荐
相关产品推荐

