5

我今天对 F# 过滤功能有一点奇怪的体验。代码是:

let rec filter : ('a -> bool) -> 'a list -> 'a list =
    fun isKept -> function
        | [] -> []
        | (x::xs) -> if isKept x then x::filter isKept xs
                     else filter isKept xs

let x = filter ((>) 1) [1; -5; -20; 30; -35; 40]

该代码返回

val x : int list = [-5; -20; -35]

问题是,当我在第一个参数 (> 1) 中传递一个条件时,我希望它会过滤掉第二个参数中大于 1 的任何列表元素,而不是相反。

有什么我看不到的明显清楚的东西吗?

4

1 回答 1

6

你的过滤功能很好。问题是这行代码:

let x = filter ((>) 1) [1; -5; -20; 30; -35; 40]

如果您使用显式 lambda 而不是部分应用(>)运算符,则等效于此代码:

let x = filter (fun x -> 1 > x) [1; -5; -20; 30; -35; 40]

原因是该(>)函数有两个参数;即使1出现在 的右侧(>),它也不会作为“正确”参数传递给函数。解决方案是(<)改用:

> let x = filter ((<) 1) [1; -5; -20; 30; -35; 40];;

val x : int list = [30; 40]

或使用显式 lambda 函数来确保以正确的顺序应用参数:

> let x = filter (fun x -> x > 1) [1; -5; -20; 30; -35; 40];;

val x : int list = [30; 40]
于 2013-09-07T13:14:53.693 回答