Reputation: 141
I'm trying to create a function that takes in a variable amount of parameters but I can't seem to find any viable solution for F#.
let expression = (fun a b -> a || b)
let expressionTriple = (fun a b c -> (a || b) && c)
// This doesn't work because expression can either be a function that takes fixed arguments
let truthTable numPredicates expression =
if numPredicates = 2 then
expression true true
else
expression true true false
truthTable 2 expression
truthTable 3 expressionTriple
How can I pass in a variable amount of arguments into the expression function?
Upvotes: 4
Views: 1064
Reputation: 21
let expression = (fun [a; b] -> a || b)
let expressionTriple = (fun [a; b; c] -> (a || b) && c)
let truthTable numPredicates expression =
if numPredicates = 2 then
expression [true; true]
else
expression [true; true; false]
truthTable 2 expression
truthTable 3 expressionTriple
Upvotes: 2
Reputation: 36708
In F#, functions with different signatures (including a different number of parameters) are considered distinct types. And any time you want to have a function take a parameter that could be two distinct types (or even a dozen distinct types), you need to use discriminated unions. Here's how you could write your code in a way that will compile and do what you're trying to do:
type Expression<'a> =
| Double of ('a -> 'a -> 'a)
| Triple of ('a -> 'a -> 'a -> 'a)
let expression = fun a b -> a || b
let expressionTriple = fun a b c -> (a || b) && c
// This works because expression is a discriminated union
let truthTable expression =
match expression with
| Double f -> f true true
| Triple f -> f true true false
truthTable (Double expression)
truthTable (Triple expressionTriple)
If you wanted to add a four-parameter version, just add a Quad of ('a -> 'a -> 'a -> 'a -> 'a)
case to that discriminated union, and so on.
If you have any questions about this, like why I wrote this with generic type 'a
instead of bool
, please feel free to ask follow-up questions.
Upvotes: 4