2016-09-07 6 views
5

Я разбирал большое количество json, манипулировал некоторыми значениями, и я хотел бы написать его обратно. Aeson расшифровывает числа на научные, но когда он кодирует его, по умолчанию, научный показывает числа в научной нотации во многих случаях, и эзон не предлагает никаких средств, которые я могу видеть, чтобы изменить это.В aeson, как вы кодируете значение Value, не приводя к научной нотации?

> 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]" 

Как я могу выписать свое значение с цифрами в более широко приемлемом формате, который могут потреблять другие языки? Давайте сделаем вид, что меня не интересуют потери точности или целые числа. У научного пакета есть средства для форматирования чисел таким образом, аэзон просто не использовал его.

>formatScientific Fixed Nothing (0.01) 
"0.01" 

>formatScientific Fixed Nothing (1000000000.1) 
"1000000000.1" 
+3

Если другие языки не могут его использовать, это проблема с их парсером JSON. [Научное обозначение является частью стандарта JSON.] (Http://www.json.org/) – Cirdec

+1

Отмечено. Мне все равно хотелось бы знать, есть ли способ сделать это, не нажимая мою собственную функцию кодирования. –

ответ

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 до сих пор печатных целых чисел без дробной части, как нормальный эсон 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]" 

Я думаю, что я подам это как ошибка отчет.

Обратите внимание, что есть также опция CustomNumberFormat, которая дает вам полный контроль над тем, как должны отображаться номера.

+0

Я должен иметь возможность извлечь хотя бы минимальный код из библиотеки. Если никто не даст лучший метод, я отмечу, что он ответил. –

1

Я искал эту функциональность перед собой; Я считаю, что в то время я пытался взаимодействовать с программой Ruby, а стандартный анализатор Ruby JSON не поддерживал научную нотацию. К сожалению, я считаю, что у aeson нет способа сделать это, поэтому вам нужно либо исправить аэзон, либо написать собственный кодер.

Дополнительную информацию можно получить: on the aeson issue tracker. Этот вопрос дополнительно предлагает использовать toEncoding по типу, отличному от Value, для достижения этого, но неясно, практично ли это в вашем случае или нет.