使用单个构造函数初始化不同数据类型的已区分联合

时间:2019-03-21 18:15:04

标签: types f# discriminated-union

说我有一个类型,例如:

type Variedvalue = I of int| S of string | F of float

是否可以创建一个函数,该函数采用一个通用参数来初始化联合的正确字段?

with static member initVariedValue (x : 'a) = 
   match x.getType() with  
   | int -> VariedValue.I x 
   | float -> VariedValue.F x
   | String -> VariedVAlue.S x

这不起作用,即使我内联它,因为在这种情况下,泛型变量被推断为int,因此永远不会达到float或string条件。 那么,有什么聪明的方法吗?还是我只需要为每个字段创建一个构造函数?

1 个答案:

答案 0 :(得分:0)

是的,您可以这样做。但是,当将意外类型传递到构造函数时,您将需要支持这种情况。我将通过返回一个Result<VariedValue, 'e>而不是直接返回一个VariedValue来做到这一点。或者,您可以抛出未处理的情况,但我认为这会破坏构造函数的预期行为。

type VariedValue = I of int| S of string | F of float

module VariedValue =
    let init (x: 'a) =
        match box x with
        | :? int as i -> I i |> Ok
        | :? string as s -> S s |> Ok
        | :? float as f -> F f |> Ok
        | _ -> Error <| sprintf "Unsupported VariedValue Type: %s" (x.GetType().Name)

示例:

> VariedValue.init 3;;
[<Struct>]
val it : Result<VariedValue,string> = Ok (I 3)

> VariedValue.init <| System.Guid.NewGuid();;
[<Struct>]
val it : Result<VariedValue,string> =
  Error "Unsupported VariedValue Type: Guid"