我想知道其他人在处理Nullable<'T>时遇到了什么在F#中。我想使用Nullable<'T>在数据类型上,以便序列化正常工作(即,不会将F#选项类型写入XML)。但是,我不希望我的代码遇到处理Nullable<'T>的丑陋问题。直。有什么建议?
使用活动模式直接匹配Nullable,或仅使用转换器选项并使用Some / None匹配是否更好?
此外,我也很乐意听到以可靠的方式处理可空引用的想法。如果我使用,说“字符串选项”,那么我最终用F#选项类型包装东西。如果我不这样做,那么我就无法区分真正的可选字符串和不应该为null的字符串。
任何机会.NET 4都会采用选项<'T>帮忙吗? (如果它是BCL的一部分,那么我们可能会看到更好的支持......)
答案 0 :(得分:2)
由于作为选项的活动模式与模式匹配很好地匹配,但似乎使用活动模式(即typeof
和??
),您的代码会吃掉更多的标记。
基本问题是你将如何处理你的可空引用?
如果你的代码是长链计算,那么使用monadic语法是很好的:
type Maybe<'a> = (unit -> 'a option)
let succeed x : Maybe<'a> = fun () -> Some(x)
let fail : Maybe<'a> = fun () -> None
let run (a: Maybe<'a>) = a()
let bind p rest = match run p with None -> fail | Some r -> (rest r)
let delay f = fun () -> run (f ())
type MaybeBuilder() =
member this.Return(x) = succeed x
member this.Let(p,rest) = rest p
member this.Bind(p,rest) = bind p rest
member this.Delay(f) = delay f
let maybe = new MaybeBuilder()
let add (a:'a) (b:'a) =
maybe {
match TryGetNumericAssociation<'a>() with
| Some v -> return (v.Add(a,b))
| _ -> return! fail
}
let add3 (a:'a) (b:'a) (c:'a) =
maybe {
let! ab = add a b
let! abc = add ab c
return abc
}
> let r1 = add 1 2;;
val r1 : (unit -> int option)
> r1();;
val it : int option = Some 3
> let r2 = add "1" "2";;
val r2 : (unit -> string option)
> r2();;
val it : string option = None
> let r3 = add3 "one" "two" "three";;
val r3 : (unit -> string option)
> r3();;
val it : string option = None