Reputation: 459
Suppose we have a number of filter functions that accept the same parameters and return a boolean result.
let filter1 _ _ = true
let filter2 _ _ = false
These can be combined into a single filter.
let combine2 f1 f2 = fun a b -> f1 a b && f2 a b
combine2 filter1 filter2
Our implementation requires some knowledge of the parameters of f1
and f2
. More generally, we may find functions combine1
... combineN
useful, where N
is the number of parameters to the filter functions. Can a generic combine
function be written that is independent of N
?
I am interested in the capabilities of F# and being able to apply this concept in other situations.
Update: My understanding of the problem is that functions succeed in ignoring any remaining parameters when they don't care whether the result is a simple type or a partially applied function. In the example above, we only reach a boolean type after applying all parameters, so they need to be specified.
Upvotes: 2
Views: 347
Reputation: 919
use high order function, passing the function as argument
let combineN invoke filters = filters |> List.map invoke |> List.reduce (&&)
and use it like this
[filter1; filter2] |> combineN (fun f -> f 1 2) |> printfn "%b"
demo: https://dotnetfiddle.net/EHC5di
you can also pass List.reduce parameter as argument, like combineN (&&) (fun f -> f 1 2)
but usually is easier to write List.map |> List.reduce
you can also use it with more arguments
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"
compiler will check types (number arguments)
//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"
see demo
Upvotes: 3