Roc 语言 List.keep_if 空列表行为深入解析:从 REPL 快照测试看过滤器语义
Roc 语言 List.keep_if 空列表行为深入解析从 REPL 快照测试看过滤器语义【免费下载链接】rocA fast, friendly, functional language.项目地址: https://gitcode.com/GitHub_Trending/ro/rocList.keep_if是 Roc 语言标准库中用于按谓词predicate过滤列表的核心函数。本文以仓库中一个专门的 REPL 快照测试 list_keep_if_empty.md 为骨架结合标准库实现源码与同族测试用例系统讲解List.keep_if的语义、空列表与全不匹配场景下的行为、底层实现原理、性能特性以及易用变体帮助读者在实战中准确使用该函数。快照测试是什么一个用例的完整解剖在 Roc 编译器的测试体系中test/snapshots/repl/目录存放的是REPL 类型的快照测试typerepl。这类测试模拟用户在 REPL 中输入表达式然后断言解释器求值后打印出的输出。本文关联的文档 list_keep_if_empty.md 内容如下# META descriptionList.keep_if on empty list returns empty list typerepl # SOURCE » List.keep_if([1, 2, 3], |_| Bool.False) # OUTPUT [] # PROBLEMS NIL按 snapshots 目录说明 的格式约定一个 REPL 快照由四部分组成META以 INI 格式描述用例description是一句话语义说明typerepl声明这是 REPL 求值测试SOURCE»前缀的行是用户在 REPL 提示符后输入的表达式本例为对三元素列表[1, 2, 3]调用List.keep_if谓词是忽略参数、恒为Bool.False的匿名函数|_| Bool.FalseOUTPUT求值器输出的真实结果这里是空列表[]PROBLEMS编译器诊断报告序列化结果NIL表示本次求值零警告、零错误类型检查完全通过。用例名称中的 empty 指的是结果为空即使输入列表非空只要谓词对每个元素都返回Bool.Falsekeep_if就会返回一个空列表[]。测试文件 list_keep_if_none.md 用更贴近业务的谓词|x| x 10验证了同一结论输出同样是[]而 list_keep_if_empty.md 采用的恒假谓词则是边界行为最直接、最不留歧义的表达。keep_if 的核心语义保留谓词为 True 的元素List.keep_if的语义在标准库源码 src/build/roc/Builtin.roc 中有权威定义Run the given function on each item of a list, and return all the items for which the function returnedBool.True.即对列表中的每个元素运行给定函数收集并返回所有函数返回Bool.True的元素。其类型签名与实现如下keep_if : List(a), (a - Bool) - List(a) keep_if |list, predicate| List.fold( list, [], |acc, item| if predicate(item) { List.concat(acc, [item]) } else { acc }, )要点拆解类型是泛型的List(a)对元素类型a完全多态谓词a - Bool只读不修改元素返回仍是List(a)元素类型不变实现基于List.fold以空列表[]为累加器从左向右遍历谓词为真时把当前元素List.concat(acc, [item])追加到结果为假时原样保留累加器——这正是过滤的经典折叠实现保持原始顺序由于是顺序折叠 尾部追加结果列表中元素的相对顺序与输入列表完全一致空输入自然得到空输出当输入是[]时List.fold不执行任何一次折叠步骤直接返回初始累加器[]。快照 list_keep_if_empty.md 验证的[1, 2, 3] 恒假谓词本质上与空输入殊途同归——List.fold的零次或多次执行都收敛到同一个空结果。同目录下的对照用例 list_keep_if.md 展示了部分保留情形List.keep_if([1, 2, 3, 4, 5], |x| x 2)输出[3.0, 4.0, 5.0]注意 REPL 中数字默认按F64打印所以整数字面量显示为带.0的形式。空结果的内存与性能特性从源码文档求证List.keep_if返回的空列表并非临时拼凑的结果其内存行为在 Builtin.roc 的文档注释中有明确的性能说明这是官方文档事实结果容量与原列表等大keep_if总是返回一个与原列表占用完全相同内存量的列表即使长度变小。原因在于实现无法预先知道结果需要多少空间如果猜测的长度过小就必须重新分配re-allocate原地可变优化如果传入的是唯一引用unique的列表keep_if会**原地修改mutate in place**来组装结果列表此时不会在堆上分配任何新内存全保留短路如果所有元素最终都被保留Roc 会原样返回原始列表不做任何拷贝。这条特性直接解释了本文主题当谓词恒为假、结果为[]时若传入的是唯一列表函数会在原地把列表清空不产生额外堆分配同时PROBLEMS: NIL表明这一过程完全静默、无诊断。文档还指出若希望过滤后收缩内存占用可以改用两次List.fold遍历的方案第一次精确计算新列表长度第二次再填充新列表见源码注释 Builtin.roc。同族函数对照drop_if、keep_if_try 与效果化变体围绕keep_if标准库提供了一组语义互补的函数在 REPL 快照中均有对应用例实战中可按需选择List.drop_if保留谓词为 False 的元素实现位于 Builtin.roc与keep_if结构完全对称只是if predicate(item)为真时跳过、为假时追加。快照 list_drop_if.md 验证List.drop_if([1, 2, 3, 4, 5], |x| x 2)输出[1.0, 2.0]——即去掉大于 2 的元素。源码文档明确其性能特性与keep_if完全相同。List.keep_if_try谓词可失败的过滤类型签名为List(a), (a - Try(Bool, err)) - Try(List(a), err)见 Builtin.roc谓词返回Try元素映射为Ok(Bool.True)时保留遇到第一个Err立即停止并返回该错误。快照 list_keep_if_try.md 给出了四条关键证据» [1, 2, 3, 4].keep_if_try(|n| Ok(n 2)) Ok([3.0, 4.0]) » [1, 2, 3].keep_if_try(|n| if n 3 { Ok(n.is_even()) } else { Err(Stop) }) Err(Stop) » [1.I64, 2, 3, 4].keep_if_try!(|n| Ok(n 2)) Ok([3, 4]) » List.keep_if_try([], |_| Ok(Bool.True)) Ok([])其中List.keep_if_try([], |_| Ok(Bool.True))输出Ok([])证明空输入或谓词恒真时keep_if_try返回的是包在Ok里的空列表而非裸[]——这正是Try版本与普通版本在空结果形态上的关键差异。第 5、6 行还用堆分配长字符串验证了keep_if_try对非内联存储元素也能正确保序返回。List.keep_if_try!效果化的过滤当谓词本身需要执行 I/O如数据库查询时使用keep_if_try!见 Builtin.roc其类型签名带能力capability约束List(a), (a Try(Bool, err)) Try(List(a), err)。与keep_if_try相同它逐元素执行谓词直到某个谓词返回Err才停止。源码文档给出了典型场景示例users.keep_if_try!(|user| SQL.query_bool!(SELECT is_active FROM users WHERE id ?, [user.id]))——即过滤出所有活跃用户任何一次查询失败即整体返回Err。如何在本地复现与验证这些行为快照测试既是回归测试也是可交互的求值说明文档。按 test/snapshots/README.md 的用法说明可以本地重现本文全部示例# 生成/校验全部快照 zig build run-snapshot-tool # 只运行单个 REPL 快照调试构建默认开启追踪 zig build run-snapshot-tool -- test/snapshots/repl/list_keep_if_empty.md # 更新该快照的期望输出PROBLEMS 部分使用 --update-expected zig build run-snapshot-tool -- test/snapshots/repl/list_keep_if_empty.md --update-expected # 开启求值器逐步追踪观察 keep_if 的折叠过程 zig build run-snapshot-tool -- test/snapshots/repl/list_keep_if_empty.md --trace-eval注意--trace-eval仅适用于typerepl快照且一次只能处理单个文件调试构建默认启用追踪发布构建需用-Dtrace-evaltrue显式开启。若想在真实 REPL 中交互式验证仓库根目录 README.md 描述了构建与运行roc的方式构建完成后直接执行roc repl然后在提示符后输入List.keep_if([1, 2, 3], |_| Bool.False)即可看到输出[]。小结从快照用例到实战要点list_keep_if_empty.md这一快照用例用最简洁的形式锁定了List.keep_if的一个关键语义过滤结果可以为空且类型检查完全静默通过PROBLEMS: NIL。将其与 Builtin.roc 的实现和文档、以及 list_keep_if.md、list_keep_if_none.md、list_keep_if_try.md、list_drop_if.md 等快照对照可以得到四条可直接用于编码的结论keep_if保留谓词为Bool.True的元素结果有序、类型不变输入为空或谓词恒假时返回[]结果列表与输入等容量传入唯一列表时可原地过滤、零堆分配全部保留时直接返回原列表需要谓词可失败如解析、校验时用keep_if_try首个Err即短路空结果形态为Ok([])谓词含 I/O 效果时用keep_if_try!语义互补的drop_if与keep_if共享完全相同的性能特征按保留什么还是丢弃什么的直觉选择即可。理解快照测试的 META / SOURCE / OUTPUT / PROBLEMS 四段结构不仅能读懂上述行为还能在修改标准库后通过zig build run-snapshot-tool快速回归验证——这正是 Roc 编译器团队用快照守护语义边界的工程实践。【免费下载链接】rocA fast, friendly, functional language.项目地址: https://gitcode.com/GitHub_Trending/ro/roc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Seedance 2.0深度调研:MMDiT架构、多镜头生成与本地部署可行性分析

Seedance 2.0深度调研:MMDiT架构、多镜头生成与本地部署可行性分析

1. 为什么Seedance 2.0值得做一次全面深度调研AI视频生成这个赛道,从2024年开始就进入了肉眼可见的爆发期。几乎每隔一两个月,就会有一个新模型或者新版本刷屏。字节跳动推出的Seedance系列,从1.0版本开始就在圈内引起了不小的关注&#xff0…

2026/9/21 18:00:24 阅读更多 →
QuickRecorder:10MB 的免费 macOS 录屏工具,系统声音也能单独录

QuickRecorder:10MB 的免费 macOS 录屏工具,系统声音也能单独录

QuickRecorder:10MB 的免费 macOS 录屏工具,系统声音也能单独录 【免费下载链接】QuickRecorder A lightweight screen recorder based on ScreenCapture Kit for macOS / 基于 ScreenCapture Kit 的轻量化多功能 macOS 录屏工具 项目地址: https://gitcode.com/GitHub_Trend…

2026/9/21 19:38:42 阅读更多 →
Unity真实地形生成:ArcGIS Maps SDK实战与性能优化

Unity真实地形生成:ArcGIS Maps SDK实战与性能优化

1. 为什么要在Unity里折腾真实地形如果你做过数字孪生、飞行模拟、城市规划演示或者户外战术类游戏,一定绕不开一个核心痛点:地形不够真。Unity自带的Terrain系统做个小山包、挖条河还行,但一旦涉及真实地理坐标、大范围地貌、卫星影像贴图&a…

2026/9/19 17:32:52 阅读更多 →

最新新闻

SpringBoot+Vue托儿所管理系统开发实践

SpringBoot+Vue托儿所管理系统开发实践

1. 项目概述作为一名从事教育信息化系统开发多年的工程师,我最近完成了一个基于SpringBoot的托儿所管理系统项目。这个系统旨在解决传统托儿所管理中存在的信息孤岛、沟通不畅和管理效率低下等问题。在实际开发过程中,我发现很多托儿所还在使用纸质档案和…

2026/9/22 0:27:01 阅读更多 →
鸿蒙Video组件开发实战:从基础到高级应用

鸿蒙Video组件开发实战:从基础到高级应用

1. 鸿蒙Video组件基础认知在鸿蒙应用开发中,多媒体播放能力是构建丰富用户体验的关键要素。VideoView作为系统提供的标准化视频播放组件,其重要性相当于Android中的VideoView或iOS的AVPlayer。这个组件封装了视频解码、渲染和播放控制的核心功能&#xf…

2026/9/22 0:27:01 阅读更多 →
面试手写字符串避坑指南:3个核心原理让你稳拿Offer

面试手写字符串避坑指南:3个核心原理让你稳拿Offer

面试手写字符串避坑指南:3个核心原理让你稳拿Offer 面试被问“手写一个字符串拼接优化”,脑子一片空白? 别慌,这不是你的错,是大多数人都没摸透底层逻辑。 这篇避坑指南,直接拆解字符串原理,让你下次面试对答如流。…

2026/9/22 0:27:01 阅读更多 →
python绘图实战避坑指南:3步搞定从教程到落地

python绘图实战避坑指南:3步搞定从教程到落地

python绘图实战避坑指南:3步搞定从教程到落地 你是不是也这样?B站刷了十个视频,CSDN收藏了五篇博客,代码看着都懂,一动手写项目就崩。图表重叠、字体乱码、数据对不上,改来改去还是不对。别急,这篇避坑指南直接给你能跑的代码。…

2026/9/22 0:27:01 阅读更多 →
3步搞定振南项目:从语法到落地的最佳实践

3步搞定振南项目:从语法到落地的最佳实践

3步搞定振南项目:从语法到落地的最佳实践 学会语法却不知怎么搭项目,这是很多开发者卡在入门到进阶之间的最大鸿沟。你背下了所有API,能写出Hello…

2026/9/22 0:27:01 阅读更多 →
祖阿曼实战项目避坑指南:3招搞定中小施工企业微服务架构

祖阿曼实战项目避坑指南:3招搞定中小施工企业微服务架构

祖阿曼实战项目避坑指南:3招搞定中小施工企业微服务架构 别被名字吓住,很多老哥以为这是啥高深理论,其实就是解决你“代码能跑但项目搭不起来”的痛点。 学会语法却不知怎么搭项目,这是绝大多数开发者从入门到进阶的卡点。…

2026/9/22 0:26:00 阅读更多 →

日新闻

3台商务办公笔记本实测:手写实现环境配置,告别卡半天

3台商务办公笔记本实测:手写实现环境配置,告别卡半天

3台商务办公笔记本实测:手写实现环境配置,告别卡半天 配置环境就卡半天?别怪机器慢,多半是你没选对工具链。在Java、Go或Python的项目现场, 手写实现…

2026/9/22 0:00:41 阅读更多 →
剑帝加点速查手册:3分钟搞懂核心逻辑

剑帝加点速查手册:3分钟搞懂核心逻辑

剑帝加点速查手册:3分钟搞懂核心逻辑 面试被问原理答不上来,是不是常态?别慌。很多开发者对着 GitHub 开源仓库里的代码发呆,看似简单实则暗藏玄机。今天这份【剑帝加点】速查手册,直接带你拆解核心实现,把面试必考的原理讲透。…

2026/9/22 0:00:41 阅读更多 →
手写实现图片压缩网站核心:搞定WebP转换与质量调优

手写实现图片压缩网站核心:搞定WebP转换与质量调优

手写实现图片压缩网站核心:搞定WebP转换与质量调优 复制来的代码跑不通不知道怎么调?别慌,这种“复制粘贴地狱”在开发圈太常见了。尤其是做 图片压缩网站…

2026/9/22 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/21 3:13:20 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/21 2:19:36 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/21 4:51:05 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/21 15:36:51 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/21 15:36:51 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →