Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Null Coalescing Operator in F#?

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?

like image 908
jbtule Avatar asked Jan 17 '14 19:01

jbtule


People also ask

Which is null coalescing operator?

The nullish coalescing operator ( ?? ) is a logical operator that returns its right-hand side operand when its left-hand side operand is null or undefined , and otherwise returns its left-hand side operand.

Why we use null coalescing operator?

operator is known as Null-coalescing operator. It will return the value of its left-hand operand if it is not null. If it is null, then it will evaluate the right-hand operand and returns its result. Or if the left-hand operand evaluates to non-null, then it does not evaluate its right-hand operand.

Is there a null coalescing operator in JavaScript?

JavaScript made sure this can be handled with its nullish operator also known as the Null Coalescing Operator, which was added to the language with ECMAScript 2020. With it, you can either return a value or assign it to some other value, depending on a boolean expression.

What is null coalescing operator in C#?

The null-coalescing operator ?? returns the value of its left-hand operand if it isn't null ; otherwise, it evaluates the right-hand operand and returns its result.


1 Answers

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.

like image 53
jbtule Avatar answered Sep 21 '22 14:09

jbtule