使用Nullable<'T>在F#中

时间:2009-09-10 17:42:32

标签: f# nullable

我想知道其他人在处理Nullable<'T>时遇到了什么在F#中。我想使用Nullable<'T>在数据类型上,以便序列化正常工作(即,不会将F#选项类型写入XML)。但是,我不希望我的代码遇到处理Nullable<'T>的丑陋问题。直。有什么建议?

使用活动模式直接匹配Nullable,或仅使用转换器选项并使用Some / None匹配是否更好?

此外,我也很乐意听到以可靠的方式处理可空引用的想法。如果我使用,说“字符串选项”,那么我最终用F#选项类型包装东西。如果我不这样做,那么我就无法区分真正的可选字符串和不应该为null的字符串。

任何机会.NET 4都会采用选项<'T>帮忙吗? (如果它是BCL的一部分,那么我们可能会看到更好的支持......)

1 个答案:

答案 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