Skip to content

Instantly share code, notes, and snippets.

@tallpeak
Last active October 21, 2015 17:21
Show Gist options
  • Select an option

  • Save tallpeak/7b8beacc8c273acecb5e to your computer and use it in GitHub Desktop.

Select an option

Save tallpeak/7b8beacc8c273acecb5e to your computer and use it in GitHub Desktop.
// from http://stackoverflow.com/questions/21194565/null-coalescing-operator-in-f
// modified to support DBNull
open System
let inline isNull value = obj.ReferenceEquals(value, null)
let inline isDBNull value = obj.ReferenceEquals(value, DBNull.Value)
type NullCoalesce =
static member Coalesce(a: 'a option, b: 'a Lazy) = match a with Some a -> a | _ -> b.Value
static member Coalesce(a: 'a Nullable, b: 'a Lazy) = if a.HasValue then a.Value else b.Value
//static member Coalesce(a: 'a when 'a:null, b: 'a Lazy) = match a with null -> b.Value | _ -> a
static member Coalesce(a: DBNull, b: 'b Lazy) = b.Value
static member Coalesce(a: obj, b: 'b Lazy) = if isDBNull a || isNull a then b.Value else a // this "takes over" the definition for 'a when 'a:null given that 'a is an obj
let inline nullCoalesceHelper< ^t, ^a, ^b, ^c when (^t or ^a) : (static member Coalesce : ^a * ^b -> ^c)> a b =
((^t or ^a) : (static member Coalesce : ^a * ^b -> ^c) (a, b))
let inline (|??) a b = nullCoalesceHelper<NullCoalesce, _, _, _> a b
// Usage:
let o = box null
let x = o |?? lazy (box 2)
let y = (DBNull.Value) |?? lazy (box 3)
let z = box (DBNull.Value) |?? lazy (box 4)
let a = None |?? lazy (box 5)
let b = box None |?? lazy (box 6)
let c = (Nullable<int>() ) |?? lazy (7)
let d = box (Nullable<int>() ) |?? lazy (box 8)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment