【发布时间】:2015-09-29 12:46:03
【问题描述】:
首先,获取一个schema并解析:
type desc = JsonProvider< """[{"name": "", "age": 1}]""", InferTypesFromValues=true >
let json = """[{"name": "Kitten", "age": 322}]"""
let typedJson = desc.Parse(json)
现在我们可以访问 typedJson.[0] .Age 和 .Name 属性,但是,我想在编译时对它们进行模式匹配,以便在架构更改时得到错误。
由于这些属性已被删除,我们无法在运行时获取它们:
let ``returns false``() =
typedJson.[0].GetType()
.FindMembers(MemberTypes.All, BindingFlags.Public ||| BindingFlags.Instance,
MemberFilter(fun _ _ -> true), null)
|> Array.exists (fun m -> m.ToString().Contains("Age"))
...我使用活动模式制作了运行时检查版本:
let (|Name|Age|) k =
let toID = NameUtils.uniqueGenerator NameUtils.nicePascalName
let idk = toID k
match idk with
| _ when idk.Equals("Age") -> Age
| _ when idk.Equals("Name") -> Name
| ex_val -> failwith (sprintf "\"%s\" shouldn't even compile!" ex_val)
typedJson.[0].JsonValue.Properties()
|> Array.map (fun (k, v) ->
match k with
| Age -> v.AsInteger().ToString() // ...
| Name -> v.AsString()) // ...
|> Array.iter (printfn "%A")
理论上,如果FSharp.Data 不是操作系统,我将无法实现toID。一般来说,整个方法似乎是错误的,需要重做。
我知道无法使用类型提供程序生成可区分联合,但也许有更好的方法在编译时进行所有这些检查?
【问题讨论】:
标签: f# type-providers f#-data