首页 > 解决方案 > F# JsonProvider 类型无法解析十进制

问题描述

为什么不能someJsonType解析9.433536880271462E-4为十进制?

自己解析值工作正常let c = decimal "9.433536880271462E-4"

#r "nuget: FSharp.Data, 3.3.3"
type someJsonType = FSharp.Data.JsonProvider<"""
{
  "point": 45.5
}
""">
let a = someJsonType.Parse "{ \"point\": 12.5 }"
let b = someJsonType.Parse "{ \"point\": 9.433536880271462E-4 }"
let c = someJsonType.Parse "{ \"point\": 0.0009433536880271462 }"
printfn "%f" a.Point // OK
printfn "%f" b.Point // exception
printfn "%f" c.Point // OK
let d = decimal "9.433536880271462E-4" // OK

例外:

System.Exception: Expecting a Decimal at '/point', got 0.0009433536880271462
   at Microsoft.FSharp.Core.PrintfModule.PrintFormatToStringThenFail@1433.Invoke(String message) in F:\workspace\_work\1\s\src\fsharp\FSharp.Core\printf.fs:line 1433
   at System.Runtime.CompilerServices.RuntimeHelpers.DispatchTailCalls(IntPtr callersRetAddrSlot, IntPtr callTarget, IntPtr retVal)
   at Microsoft.FSharp.Core.OptimizedClosures.Invoke@3298-1.Invoke(T2 u, T3 v) in F:\workspace\_work\1\s\src\fsharp\FSharp.Core\prim-types.fs:line 3298
   at <StartupCode$FSI_0072>.$FSI_0072.main@()
Stopped due to error

标签: f#type-providersf#-data

解决方案


数据类型被推断为decimal,但 bfloat因此是例外。这是一个怪癖,意味着您必须修改示例 json 以确保推断出正确的类型。所以,如果你想推断,float那么你必须修改你的样本:

#r "nuget: FSharp.Data, 3.3.3"
type someJsonType = FSharp.Data.JsonProvider<"""
{
  "point": 9.433536880271462E-4
}
""">
let a = someJsonType.Parse "{ \"point\": 12.5 }"
let b = someJsonType.Parse "{ \"point\": 9.433536880271462E-4 }"
let c = someJsonType.Parse "{ \"point\": 0.0009433536880271462 }"
printfn "%f" a.Point // val a.Point is float with get
printfn "%f" b.Point // OK
printfn "%f" c.Point // OK

如果你想要它,decimal你可以在将 json 数据加载到本地对象后进行转换。这就是你实际上正在做的事情let d = decimal "9.433536880271462E-4" // OK

(类似地,如果 json 模式旨在提供浮点数或小数,但示例仅具有看似 int 的内容,则会推断出 int,因此您必须再次修改示例以确保推断出正确的类型)

JsonProvider 只能处理样本 json 中现有的内容,因此样本有助于推理的重要性。

(注意:如果来自实时第三方站点,我们并不总是可以控制示例 json,所以我认为某种形式的类型注释可能有助于提供帮助,但据我所知,这还不存在。)


推荐阅读