代码之家  ›  专栏  ›  技术社区  ›  MichaelGG

在f中使用nullable<'t>#

  •  4
  • MichaelGG  · 技术社区  · 16 年前

    我想知道其他人对f_中的nullable<'t>有何看法。我希望在数据类型上使用nullable<'t>,以便序列化正常工作(即,不将f选项类型写出为XML)。但是,我不希望我的代码停留在直接处理nullable的丑陋上。有什么建议吗?

    是使用活动模式直接在可为空的情况下进行匹配,还是只使用转换器到选项并使用某些/无匹配?

    另外,我也很乐意听到一些关于处理可以为空的引用的想法。如果我使用,比如说“字符串选项”,那么我最终会得到f选项类型的包装。如果不这样做,我就无法区分真正可选的字符串和不应该为空的字符串。

    有没有可能.NET 4会提供一个选项来帮助您?(如果它是BCL的一部分,那么我们可能会看到对它更好的支持…)

    1 回复  |  直到 16 年前
        1
  •  2
  •   ssp    16 年前

    与活动模式一样,选项在模式匹配中起着很好的作用,但似乎是通过使用活动模式(即 typeof ?? )你的代码会吃掉更多的虱子。 基本问题是,如何处理可以为空的引用? 如果您的代码是长链计算,那么最好使用一元语法:

    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