F# 在F中编写自己版本的List.filter#

F# 在F中编写自己版本的List.filter#,f#,F#,我正在尝试手动重写List.filter 到目前为止,我有: let rec filter f = function |[] -> [] |x::xs -> if f x = true then x @ filter f xs else filter f xs;; 操作员@在中添加两个列表,因此x如果。。。然后。。。else表达式应为list类型。 您可能打算使用list cons操作符:。此外,您不需要将函数f应用程序的结果与true进

我正在尝试手动重写List.filter 到目前为止,我有:

let rec filter f = function
    |[] -> []
    |x::xs -> if f x = true then x @ filter f xs
              else filter f xs;;

操作员
@
中添加两个列表,因此
x
如果。。。然后。。。else
表达式应为
list
类型。 您可能打算使用list cons操作符
。此外,您不需要将函数
f
应用程序的结果与
true
进行比较

let rec filter f = function
    |[] -> []
    |x::xs -> if f x then x :: filter f xs
              else filter f xs

[1;2;3;4;5;6;7;8;9] |> filter (fun x -> x % 2 = 0)
val it:int list=[2;4;6;8]


注意:此函数不是尾部递归函数,因此在大列表中会出现堆栈溢出异常。

运算符
@
中附加两个列表,因此
x
如果。。。然后。。。else
表达式应为
list
类型。 您可能打算使用list cons操作符
。此外,您不需要将函数
f
应用程序的结果与
true
进行比较

let rec filter f = function
    |[] -> []
    |x::xs -> if f x then x :: filter f xs
              else filter f xs

[1;2;3;4;5;6;7;8;9] |> filter (fun x -> x % 2 = 0)
val it:int list=[2;4;6;8]


注意:此函数不是尾部递归函数,因此在大列表中会出现堆栈溢出异常。

我要补充一点,即识别和应用函数模式可能与掌握递归和模式匹配同样重要。可能第一种模式是

通过折叠实现您的任务需要简洁:

let filter p ls = List.foldBack (fun l acc -> if p l then l::acc else acc) ls []

我想补充一点,即识别和应用函数模式可能与掌握递归和模式匹配同样重要。可能第一种模式是

通过折叠实现您的任务需要简洁:

let filter p ls = List.foldBack (fun l acc -> if p l then l::acc else acc) ls []

我在理解您的实现方面有点困难,您能对此发表意见吗?这可能是因为对列表缺乏正确的理解。
.foldback
,但是
->
之后的部分让我有点困惑。@Left4Cookies:
列表。foldback
允许您使用
保存元素的原始顺序来构建过滤列表;如果改用
List.fold
,则需要将
List.rev
应用于过滤后的列表,以恢复原始顺序。至于
如果pl那么l::acc else acc
-这里没有魔法:如果当前元素
l
的谓词
p
true
,那么
cons
l
到累加器
acc
,否则只需通过
acc
。运行一个快速而肮脏的示例可能有助于理解。我在理解您的实现方面有点困难,您能对此发表评论吗?这可能是因为对列表缺乏正确的理解。
.foldback
,但是
->
之后的部分让我有点困惑。@Left4Cookies:
列表。foldback
允许您使用
保存元素的原始顺序来构建过滤列表;如果改用
List.fold
,则需要将
List.rev
应用于过滤后的列表,以恢复原始顺序。至于
如果pl那么l::acc else acc
-这里没有魔法:如果当前元素
l
的谓词
p
true
,那么
cons
l
到累加器
acc
,否则只需通过
acc
。运行一个快速且脏的示例可能有助于理解。