我已经解析了大量的json,操纵了一些值,我想把它写回来。 Aeson将数字解码为科学,但是当它编码时,默认情况下,科学在许多情况下以科学记数法显示数字,而且aeson没有提供任何我可以看到的改变它的方法。
> decode "[\"asdf\", 1, 1.0, 1000000000.1, 0.01]" :: Maybe Value
Just (Array [String "asdf",Number 1.0,Number 1.0,Number 1.0000000001e9,Number 1.0e-2])
encode (Array [String "asdf",Number 1.0,Number 1.0,Number 1.0000000001e9,Number 1.0e-2])
"[\"asdf\",1,1,1.0000000001e9,1.0e-2]"
> encode (Array [String "asdf", Number 1, Number 1.0, Number 1000000000.1, Number 0.01])
"[\"asdf\",1,1,1.0000000001e9,1.0e-2]"
如何用更广泛接受的格式用其他语言可以使用的数字写出我的值?让我们假装我不关心精度损失或整数溢出。科学软件包具有以这种方式格式化数字的方法,aeson恰好没有使用它。
>formatScientific Fixed Nothing (0.01)
"0.01"
>formatScientific Fixed Nothing (1000000000.1)
"1000000000.1"
答案 0 :(得分:4)
pretty printer for Aeson(仅限0.8版本,非常近期)有一个配置选项,可以完全满足您的要求:
Prelude> :m +Data.Aeson Data.Aeson.Encode.Pretty
Prelude Data.Aeson Data.Aeson.Encode.Pretty> encodePretty' (defConfig{confNumFormat=Decimal}) (Array [String "asdf",Number 1.0,Number 1.0,Number 1.0000000001e9,Number 1.0e-2])
"[\n \"asdf\",\n 1.0,\n 1.0,\n 1000000000.1,\n 0.01\n]"
不幸的是,这台漂亮的打印机现在将实际的整数输出为1.0
而不是1
,我认为这比用科学计数法打印小数要严重得多(这在任何地方都应该是正常的) )。使用默认设置也会发生这种情况:
Prelude Data.Aeson Data.Aeson.Encode.Pretty> encodePretty (Array [String "asdf",Number 1.0,Number 1.0,Number 1.0000000001e9,Number 1.0e-2])
"[\n \"asdf\",\n 1.0,\n 1.0,\n 1.0000000001e9,\n 1.0e-2\n]"
版本0.7.2仍然打印整数而没有小数部分,就像正常的aeson encode
那样:
aeson-pretty-0.7.2:Data.Aeson.Encode.Pretty> encodePretty (Array [String "asdf",Number 1.0,Number 1.0,Number 1.0000000001e9,Number 1.0e-2])
"[\n \"asdf\",\n 1,\n 1,\n 1.0000000001e9,\n 1.0e-2\n]"
我想我会将此作为错误报告提交。
请注意,还有一个Custom
NumberFormat
选项,可让您完全控制数字的显示方式。
答案 1 :(得分:1)
我在自己面前寻找过这个功能;我相信那时我正在尝试与Ruby程序接口,而标准的Ruby JSON解析器并不支持科学记数法。不幸的是,我相信aeson无法做到这一点,所以你需要修补aeson或编写自己的编码器。
还有更多细节on the aeson issue tracker。该问题还建议在toEncoding
以外的类型上使用Value
来实现此目的,但不清楚这是否适用于您的情况。