简体   繁体   中英

Int Option instead of Int in F#

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM