Skip to content

Instantly share code, notes, and snippets.

@jovaneyck
Last active May 25, 2016 10:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jovaneyck/706f19eb5aa80b4bfa75a2568dbcdd69 to your computer and use it in GitHub Desktop.
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?
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 @>
@deapsquatter
Copy link

deapsquatter commented May 25, 2016

How about a using a match:

let add x y =
  match x,y with
  |Some x,Some y -> Some (x + y)
  |_ -> None

@deapsquatter
Copy link

Shorter version using Option.bind2:

let add = Option.bind2 (fun x y -> Some (x + y))

@jovaneyck
Copy link
Author

Ahh, tweet-sized solutions. Thanks very much!
Is Option.bind2 a standard function? I can't seem find a reference to it.

@neoeinstein
Copy link

neoeinstein commented May 25, 2016

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