5

Many APIs that I consume from F# allow null values. I like turning them into Options. Is there a simple built-in way to do this? Here is one way I have done so:

type Option<'A> with
    static member ofNull (t:'T when 'T : equality) =
        if t = null then None else Some t

Then I'm able to use Option.ofNull like so:

type XElement with
    member x.El n = x.Element (XName.Get n) |> Option.ofNull

Is there something built-in that already does this?

Based on Daniel's answer, equality isn't needed. null constraint can be used instead.

type Option<'A> with
    static member ofNull (t:'T when 'T : null) =
        if t = null then None else Some t
Cameron Taggart
  • 5,771
  • 4
  • 45
  • 70

1 Answers1

6

There's nothing built-in to do this. BTW, you can do without the equality constraint:

//'a -> 'a option when 'a : null
let ofNull = function
    | null -> None
    | x -> Some x

or, if you want to handle F# values passed from other languages and Unchecked.defaultof<_>:

//'a -> 'a option
let ofNull x = 
    match box x with
    | null -> None
    | _ -> Some x
Daniel
  • 47,404
  • 11
  • 101
  • 179
  • 1
    As you say, for the purposes of this function, it's better not to have the `null` constraint on the type parameter, but I'm not sure boxing is the best way to remove the type constraint here -- why does it make sense for this function to accept value types? Another way to implement this would be to manually specify the `not struct` constraint on the type parameter, then use `System.Object.ReferenceEquals(null, x)` to check for null. – Jack P. Jul 06 '14 at 14:53
  • @JackP.: Those are reasonable improvements. Of course, you could avoid `box` with just a type annotation: `let ofNull (x: obj) = ...` – Daniel Jul 07 '14 at 03:24