I've got a function that takes two parameters, for example:
let f a b = a = b
Then I have a second function that returns a tuple:
let g = (a, b)
I want to pass in a and b in the tuple from g as parameters to f in one line. I could do it in two statements, but the reason I want to do this is that my calling function does an or and I'd rather not call f unless the first case is false, to save on unnecessary processing.
let calling =
someboolean ||
f g // want to split result of g to parameters for f without calling g twice
Any tips on how to do this? I know I could have f take a tuple instead, but I'd like to retain the option for currying.
I hope I explained this well enough. :)
You can also do:
let calling = someBoolean || g ||> f
Because:
(||>) : ('a * 'b -> ('a -> 'b -> 'c) -> 'c)
(And similarly (|||>) : ('a * 'b * 'c -> ('a -> 'b -> 'c -> 'd) -> 'd)
)
You can define a function which converts a curried function into one which takes a pair argument:
uncurry f (a, b) = f a b
let calling = someBoolean || (uncurry f) g
You can extract from the tuple inline, you'll still get the benefit of the short-circuiting.
let calling = someBoolean || let a,b = g in f a b
As already mentioned, you could define the uncurry
combinator to convert function taking two arguments into a function taking tuple.
However I'd recommend not doing that - that style of programming is not really idiomatic in F# (unlike, say, in Haskell) and I think it makes code hard to read, debug and maintain.
So, what to do instead?
If the two values logically belong together (represent some entity used elsewhere in your code) then change f
to take a tuple too.
If they are just two values, then use let
and pattern matching to decompose the tuple. This will be longer, but you'll have to name the components, which will improve readability.
In your sample g
is actually a value so you can write just:
let someThing, otherThing = g
boolThing || (f someThing otherThing)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With