F# 在创建 union case 值时如何指定将什么值设置到哪个字段?

F# how to specify when creating union case value what value to set to which field?

我有一个字典,其中键是字段名,值是这个字段值。是否有可能以某种方式明确指示使用该字典为哪个字段分配什么值?或者是将第二个参数传递给 FSharpValue.MakeUnion?

时坚持字段声明顺序的唯一方法

两种不同的方法:

  1. 如果名称完全匹配,并且您愿意“在将第二个参数传递给 FSharpValue.MakeUnion 时坚持字段声明的顺序”,您可以这样做:
open FSharp.Reflection

let instantiate (unionCase : UnionCaseInfo) (dict : Map<_, _>) =
    let args =
        unionCase.GetFields()
            |> Array.map (fun field ->
                 dict.[field.Name] :> obj)
    FSharpValue.MakeUnion(unionCase, args)

用法示例:

type MyType = UnionCase of a : int * b : int * c : int

let unionCase =
    FSharpType.GetUnionCases(typeof<MyType>)
        |> Array.exactlyOne

let dict =
    Map [
        "a", 1
        "b", 2
        "c", 3
    ]

instantiate unionCase dict
    :?> MyType
    |> printfn "%A"

输出为:

UnionCase (1, 2, 3)
  1. 如果你想避免反射,你可以按你想要的任何顺序分配给字段,就像这样:
    UnionCase (
        c = dict.["c"],
        b = dict.["b"],
        a = dict.["a"])