F#中的空合并运算符? [英] Null Coalescing Operator in F#?
问题描述
与C#库进行交互时,我发现自己想要C#的null合并运算符同时用于Nullable
结构和引用类型.
When interacting with C# libraries, I find myself wanting C#'s null coalescing operator both for Nullable
structs and reference types.
是否可以用一个内联适当的if
情况的单个重载运算符在F#中对此进行近似?
Is it possible to approximate this in F# with a single overloaded operator that inlines the appropriate if
case?
推荐答案
是的,使用此 SO 答案中的一些小骇客"F#中的重载运算符".
Yes, using some minor hackery found in this SO answer "Overload operator in F#".
在编译时,可以内嵌对于单个运算符使用('a Nullable, 'a) ->'a
或('a when 'a:null, 'a) -> 'a
的正确重载.甚至可以抛出('a option, 'a) -> 'a
以获得更大的灵活性.
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.
为了提供更接近于c#运算符的行为,我设置了默认参数'a Lazy
,以便除非原始值为null
,否则不会调用其源.
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
.
示例:
let value = Something.PossiblyNullReturned()
|?? lazy new SameType()
实施方式:
NullCoalesce.fs [要点]:
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
或者,我制作了一个库,该库利用此技术以及用于处理Null/Option/Nullables的计算表达式,称为
Alternatively I made a library that utilizes this technique as well as computation expression for dealing with Null/Option/Nullables, called FSharp.Interop.NullOptAble
它改用运算符|?->
.
这篇关于F#中的空合并运算符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!