Null Coalescing Operator in F#?
f#, null, null-coalescing, null-coalescing-operator
Solution
Yes, using some minor hackery found in this SO answer "Overload operator in F#".
At compiled time the correct overload for an usage of either `('a Nullable, 'a) ->'a` or `('a when 'a:null, 'a) -> 'a` for a single operator can be inlined. Even `('a option, 'a) -> 'a` can be thrown in for more flexibility.
To provide closer behavior to c# operator, I've made default parameter `'a Lazy` so that it's source isn't called unless the original value is `null`.
Example:
let value = Something.PossiblyNullReturned()
|?? lazy new SameType()
Implementation:
NullCoalesce.fs [Gist]:
//https://gist.github.com/jbtule/8477768#file-nullcoalesce-fs
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
let inline nullCoalesceHelper< ^t, ^a, ^b, ^c when (^t or ^a) : (static member Coalesce : ^a * ^b -> ^c)> a b =
// calling the statically inferred member
((^t or ^a) : (static member Coalesce : ^a * ^b -> ^c) (a, b))
let inline (|??) a b = nullCoalesceHelper<NullCoalesce, _, _, _> a b
Alternatively I made a library that utilizes this technique as well as computation expression for dealing with Null/Option/Nullables, called FSharp.Interop.NullOptAble
It uses the operator `|?->` instead.
Problem
When interacting with C# libraries, I find myself wanting C#'s null coalescing operator both for `Nullable` structs and reference types. Is it possible to approximate this in F# with a single overloaded operator that inlines the appropriate `if` case?