use*_*438 5 f# functional-programming
今天我对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]
Run Code Online (Sandbox Code Playgroud)
该代码返回
val x : int list = [-5; -20; -35]
Run Code Online (Sandbox Code Playgroud)
问题是,当我在第一个参数(> 1)中传递一个条件时,我希望它会过滤掉第二个参数的任何大于1的列表元素,而不是相反的.
有什么明显的东西我无法发现吗?
你的过滤功能很好.问题是这行代码:
let x = filter ((>) 1) [1; -5; -20; 30; -35; 40]
Run Code Online (Sandbox Code Playgroud)
如果您使用显式lambda而不是部分应用(>)运算符,则等效于此代码:
let x = filter (fun x -> 1 > x) [1; -5; -20; 30; -35; 40]
Run Code Online (Sandbox Code Playgroud)
原因是该(>)函数有两个参数; 即使它1出现在右侧(>),它也不会作为函数的"正确"参数传递.解决方案是使用(<):
> let x = filter ((<) 1) [1; -5; -20; 30; -35; 40];;
val x : int list = [30; 40]
Run Code Online (Sandbox Code Playgroud)
或者使用显式lambda函数来确保以正确的顺序应用参数:
> let x = filter (fun x -> x > 1) [1; -5; -20; 30; -35; 40];;
val x : int list = [30; 40]
Run Code Online (Sandbox Code Playgroud)