假设我们有许多过滤函数接受相同的参数并返回一个布尔结果。
let filter1 _ _ = true
let filter2 _ _ = false
这些可以组合成一个过滤器。
let combine2 f1 f2 = fun a b -> f1 a b && f2 a b
combine2 filter1 filter2
我们的实施需要了解f1
和f2
的参数。更一般地,我们可能会发现函数combine1
... combineN
很有用,其中N
是过滤函数的参数数量。是否可以编写与combine
无关的通用N
函数?
我对F#的功能很感兴趣,并且能够在其他情况下应用这个概念。
更新:我对问题的理解是,当函数不关心结果是简单类型还是部分应用函数时,函数会成功忽略任何剩余参数。在上面的例子中,我们只在应用所有参数后达到布尔类型,因此需要指定它们。
答案 0 :(得分:2)
使用高阶函数,将函数作为参数传递
let combineN invoke filters = filters |> List.map invoke |> List.reduce (&&)
并像这样使用
[filter1; filter2] |> combineN (fun f -> f 1 2) |> printfn "%b"
演示:https://dotnetfiddle.net/EHC5di
您也可以将List.reduce参数作为参数传递,例如combineN (&&) (fun f -> f 1 2)
但通常更容易编写List.map |> List.reduce
您也可以使用更多参数
let filter3 _ _ _ = true
let filter4 _ _ _ = true
[filter3; filter4] |> List.map (fun f -> f 1 2 3) |> List.reduce (&&) |> printfn "%b"
[filter3; filter4] |> combineN (fun f -> f 1 2 3) |> printfn "%b"
编译器将检查类型(数字参数)
//call list of function with 2 argument, with more arguments doesnt compile
[filter1; filter2] |> combineN (fun f -> f 1 2 3) |> printfn "%b"
//mix functions with different arguments, doesnt compile either
[filter1; filter3] |> combineN (fun f -> f 1 2 3) |> printfn "%b"
参见演示