f# null null-coalescing-operator null-coalescing

¿Operador de fusión nulo en F#?



null null-coalescing-operator (2)

Al interactuar con las bibliotecas de C #, me encuentro con ganas de que el operador de Nullable nula de C #, tanto para Nullable estructuras Nullable como para los tipos de referencia.

¿Es posible aproximar esto en F # con un solo operador sobrecargado que inscribe el caso apropiado?


modificó share por jbtule para soportar DBNull:

//https://gist.github.com/tallpeak/7b8beacc8c273acecb5e 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 // overridden, so removed static member Coalesce(a: DBNull, b: ''b Lazy) = b.Value //added to support DBNull // The following line overrides the definition for "''a when ''a:null" static member Coalesce(a: obj, b: ''b Lazy) = if isDBNull a || isNull a then b.Value else a // support box DBNull 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))

Uso:

let inline (|??) a b = nullCoalesceHelper<NullCoalesce, _, _, _> a b 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)


Sí, utilizando un poco de piratería que se encuentra en esta respuesta de SO " Operador de sobrecarga en F # ".

En el momento de la (''a Nullable, ''a) ->''a la sobrecarga correcta para el uso de cualquiera (''a Nullable, ''a) ->''a o (''a when ''a:null, ''a) -> ''a para un solo operador. Incluso (''a option, ''a) -> ''a puede ser lanzado para una mayor flexibilidad.

Para proporcionar un comportamiento más cercano al operador c #, he hecho que el parámetro por defecto ''a Lazy para que no se llame a la fuente a menos que el valor original sea null .

Ejemplo:

let value = Something.PossiblyNullReturned() |?? lazy new SameType()

Implementación:

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

Alternativamente , hice una biblioteca que utiliza esta técnica, así como una expresión de cálculo para tratar con Null / Option / Nullables, llamada FSharp.Interop.NullOptAble

Utiliza el operador |?-> lugar.