Null Coalescing Operator in F#?

前端 未结 3 1954
长情又很酷
长情又很酷 2020-12-05 02:36

When interacting with C# libraries, I find myself wanting C#\'s null coalescing operator both for Nullable structs and reference types.

Is it possible t

3条回答
  •  感情败类
    2020-12-05 03:38

    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 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.

提交回复
热议问题