2016-09-07 13 views
5

Przetworzyłem dużą ilość jsonów, zmanipulowałem niektóre wartości i chciałbym je zapisać. Aeson dekoduje liczby do danych naukowych, ale kiedy je koduje, domyślnie, w wielu przypadkach naukowych pokazuje liczby w notacji naukowej, a aeson nie oferuje żadnych środków, które mogę zobaczyć, aby to zmienić.W aeson, w jaki sposób kodujesz z wartości bez tworzenia notacji naukowej?

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

Jak mogę zapisać moją wartość liczbową w bardziej akceptowalnym formacie, który mogą spożywać inne języki? Udawajmy, że nie chodzi mi o precyzję strat lub przepełnienie liczb całkowitych. Pakiet naukowy ma środki do formatowania liczb w ten sposób, aeson zwyczajnie go nie użył.

>formatScientific Fixed Nothing (0.01) 
"0.01" 

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

Jeśli inne języki nie mogą go używać, jest to problem z ich parserem JSON. [Notacja naukowa jest częścią standardu JSON.] (Http://www.json.org/) – Cirdec

+1

Noted. Nadal chciałbym wiedzieć, czy istnieje sposób, aby to zrobić bez pisania własnej funkcji kodowania. –

Odpowiedz

4

pretty printer for Aeson (dopiero od wersji 0.8, całkiem niedawno) posiada opcję konfiguracji, który robi dokładnie to, o co prosisz:

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

Niestety, to dość-drukarka drukuje teraz rzeczywistych liczb całkowitych jako 1.0 zamiast z 1, które uważam za znacznie poważniejszy problem niż drukowanie cyfr po przecinku w notacji naukowej (która tak naprawdę powinna być wszędzie dobra). Dzieje się tak również przy ustawieniach domyślnych:

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

Version 0.7.2 nadal drukowane liczb całkowitych bez części ułamkowej, jak normalnego ajzon encode robi:

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

Myślę, że plik to jako błąd raport.

Należy pamiętać, że dostępna jest również opcja CustomNumberFormat, która zapewnia pełną kontrolę nad tym, jak powinny wyglądać liczby.

+0

Powinienem być w stanie wyodrębnić przynajmniej minimalny kod z biblioteki przynajmniej. Jeśli nikt nie da lepszej metody, zaznaczę odpowiedź. –

1

Szukałem tej funkcji przed siebie; Wierzę, że w tym czasie próbowałem nawiązać połączenie z programem Ruby, a standardowy analizator składni JSON nie obsługiwał notacji naukowej. Niestety uważam, że aeson nie ma sposobu, aby to zrobić, więc będziesz musiał albo załatać aeson, albo napisać własny koder.

Istnieją dalsze szczegóły on the aeson issue tracker. Ta kwestia dodatkowo sugeruje użycie toEncoding na innym typie niż Value, aby to osiągnąć, ale nie jest jasne, czy jest to praktyczne w twoim przypadku, czy nie.

Powiązane problemy