将功能与相同但部分未知的签名组合在一起

时间:2014-09-05 01:34:08

标签: f#

假设我们有许多过滤函数接受相同的参数并返回一个布尔结果。

let filter1 _ _ = true
let filter2 _ _ = false

这些可以组合成一个过滤器。

let combine2 f1 f2 = fun a b -> f1 a b && f2 a b
combine2 filter1 filter2

我们的实施需要了解f1f2的参数。更一般地,我们可能会发现函数combine1 ... combineN很有用,其中N是过滤函数的参数数量。是否可以编写与combine无关的通用N函数?

我对F#的功能很感兴趣,并且能够在其他情况下应用这个概念。

更新:我对问题的理解是,当函数不关心结果是简单类型还是部分应用函数时,函数会成功忽略任何剩余参数。在上面的例子中,我们只在应用所有参数后达到布尔类型,因此需要指定它们。

1 个答案:

答案 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"

参见演示