Last active
May 25, 2016 10:52
-
-
Save jovaneyck/706f19eb5aa80b4bfa75a2568dbcdd69 to your computer and use it in GitHub Desktop.
I'm trying to define a function with type signature (int option -> int option -> int option). It results in a Some containing the sum or None when one of the arguments is None. I have an implementation but it looks needlessly verbose. Is there a more idiomatic way to achieve this?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let add : (int option -> int option -> int option) = | |
(fun fst snd -> | |
fst | |
|> Option.bind | |
(fun f -> | |
snd | |
|> Option.bind (fun s -> Some (f + s)))) | |
test <@ add (Some 1) (Some 2) = Some 3 @> | |
test <@ add None (Some 2) = None @> | |
test <@ add (Some 1) None = None @> |
Shorter version using Option.bind2:
let add = Option.bind2 (fun x y -> Some (x + y))
Ahh, tweet-sized solutions. Thanks very much!
Is Option.bind2 a standard function? I can't seem find a reference to it.
Option.map2
is a bit simpler. It's not defined in the FSharp.Core, but you can find it in other libraries like ExtCore.
For cases following the patern of applying a function to an arbitrary number of arguments which are in a structure (such as Option or List), there is a concept of an Applicative with a corresponding apply
function. I've defined the function for Option below. You can think of it as reading "and map".
let apply x f =
match f, x with
| Some g, Some v -> Some (g v)
| _ -> None
let addTwoOpts a b =
Option.map (+) a |> apply b
let addThreeOpts a b c =
Option.map (fun x y z -> x + y + z) a |> apply b |> apply c
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
How about a using a match: