cadull
cadull

Reputation: 459

Combining functions with the same, but partially unknown signature

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

Answers (1)

Enrico Sada
Enrico Sada

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

Related Questions