I am having trouble with the following:
let safeDiv x y =
match (x,y) with
| (_, Some 0) -> None
| (Some xx, Some yy) -> Some (xx/yy)
| _ -> None
When I go to run this simple function in the interactive window of Visual Studio like so:
safeDiv 4 2
I get the following error...
This expression was expected to have type int option but here has type int.
Could it be I'm meant to use safeDiv
Some(4)
Some(2)
? This doesn't work either...
Ok, this is overkill but I actually did something similar to this recently.
First I defined a computation expression builder for the option type:
type OptionBuilder() =
member this.Bind(x, f) = Option.bind f x
member this.Return(x) = Some x
member this.ReturnFrom(x) = x
let opt = new OptionBuilder()
And then I defined a function sub of type float -> float -> float option
let sub x y = if y = 0.0 then None else Some (x / y)
And finally I used the OptionBuilder to define saveDiv as float option -> float option -> float option
let safeDiv x y = opt { let! a = x
let! b = y
return! sub a b }
You can read more about computation expressions on wikibooks: http://en.wikibooks.org/wiki/F_Sharp_Programming/Computation_Expressions
And if you want to dive deeper into the theory behind this, you can read this paper by Tomas Petricek and Don Syme: http://www.cl.cam.ac.uk/~tp322/drafts/notations.pdf
Your second version was close.
It should be
safeDiv (Some(4)) (Some(2))
The extra brackets are required to make sure that functions are applied in the correct order.
You constructed a function that has the signature safeDiv : int option -> int option -> int option
. You need to use an entry like safeDiv (Some 4) (Some 2)
to use your function as is.
The problem is in the matching of (4, 2), of type int*int, with the expressions (_, Some 0) and (Some xx, Some yy). The whole function can be simplified:
let safeDiv x y =
match (x,y) with
| (_, 0) -> None
| (_, _) -> Some (x/y)
Making the following call valid
safeDiv 4 2