在SML中手动实现filter函数:else分支返回值困惑求助
手动实现SML Filter函数的修正方案
嘿,我看你在手动实现SML的filter功能时遇到了点小问题——你的代码现在会把不小于5的元素替换成0,但这其实不是filter该做的事,filter的核心是移除不符合条件的元素,而不是用其他值替换它们。
你的代码问题分析
你当前的代码:
fun Filter[] = [] | Filter(x::xs) = let fun lessthan x = if x < 5 then x else 0 in lessthan(x)::Filter(xs) end;
不管x是否小于5,都会将lessthan(x)的结果(要么是x,要么是0)拼接到递归结果前,这就导致不满足条件的元素被换成0留在了列表里,不符合filter“只保留符合条件元素”的预期。
修正后的代码
我们可以直接在模式匹配的分支里做条件判断,跳过不符合条件的元素:
fun Filter [] = [] | Filter (x::xs) = if x < 5 then x :: Filter xs else Filter xs;
代码解释
- 空列表的情况:和你原来的实现一致,返回空列表
[],这是递归的终止条件。 - 非空列表的情况:
- 如果
x < 5(满足条件),就把x放在递归处理剩余列表xs得到的结果前面,相当于保留这个元素。 - 如果
x >=5(不满足条件),直接返回递归处理xs的结果,相当于跳过当前元素,不把它加入最终列表。
- 如果
更通用的版本(可选)
如果你想让这个函数和标准库的filter一样,能接受任意的判断函数(而不是硬编码x<5),可以改成这样:
fun filter _ [] = [] | filter pred (x::xs) = if pred x then x :: filter pred xs else filter pred xs;
使用的时候只需要传入判断逻辑,比如筛选小于5的元素:
filter (fn x => x < 5) [1, 6, 3, 7, 2]; (* 结果是 [1,3,2] *)
内容的提问来源于stack exchange,提问作者Tuffie
相关产品推荐
相关产品推荐

