2016-09-07 16 views
5

Tôi đã phân tích cú pháp một lượng lớn json, thao tác một số giá trị và tôi muốn viết lại. Aeson giải mã số vào khoa học, nhưng khi nó mã hóa nó, theo mặc định, khoa học cho thấy các con số trong ký hiệu khoa học trong nhiều trường hợp, và aeson không cung cấp bất kỳ phương tiện nào mà tôi có thể thấy để thay đổi điều đó.Trong aeson, làm thế nào để bạn mã hóa từ một giá trị mà không dẫn đến ký pháp khoa học?

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

Làm cách nào để ghi giá trị bằng các định dạng được chấp nhận rộng rãi hơn? Giả sử tôi không quan tâm đến việc mất chính xác hoặc tràn số nguyên. Gói khoa học có các phương tiện để định dạng các con số theo cách này, aeson chỉ xảy ra không sử dụng nó.

>formatScientific Fixed Nothing (0.01) 
"0.01" 

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

Nếu các ngôn ngữ khác không thể sử dụng nó, đó là vấn đề với trình phân tích cú pháp JSON của chúng. [Ký pháp khoa học là một phần của tiêu chuẩn JSON.] (Http://www.json.org/) – Cirdec

+1

Lưu ý. Tôi vẫn muốn biết nếu có một cách để làm điều đó mà không cần viết chức năng mã hóa của riêng tôi. –

Trả lời

4

Các pretty printer for Aeson (chỉ kể từ phiên bản 0.8, khá gần đây) có một tùy chọn cấu hình thực hiện chính xác những gì bạn đang yêu cầu:

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

Thật không may, điều này khá-in tại đầu ra những con số không thể thiếu thực tế như 1.0 thay của 1, mà tôi xem xét một vấn đề nghiêm trọng hơn nhiều so với in số thập phân trong ký hiệu khoa học (mà thực sự nên được ok ở khắp mọi nơi). Điều này cũng xảy ra với các thiết lập mặc định:

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 nguyên vẫn in mà không cần phần phân đoạn, như aeson bình thường encode làm:

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

Tôi nghĩ rằng tôi sẽ nộp này là một lỗi bài báo cáo.

Lưu ý rằng cũng có tùy chọn CustomNumberFormat, cho phép bạn kiểm soát hoàn toàn về cách số sẽ xuất hiện.

+0

Tôi sẽ có thể trích xuất một số mã tối thiểu từ thư viện ít nhất. Nếu không có ai đưa ra một phương pháp tốt hơn, tôi sẽ đánh dấu nó là đã trả lời. –

1

Tôi đã tìm kiếm chức năng này trước bản thân mình; Tôi tin vào thời điểm đó tôi đã cố gắng giao tiếp với một chương trình Ruby và trình phân tích cú pháp chuẩn của JSON JSON không hỗ trợ ký hiệu khoa học. Thật không may tôi tin rằng aeson không có một cách để làm điều đó, vì vậy bạn sẽ cần phải hoặc là vá aeson hoặc viết bộ mã hóa của riêng bạn.

Có biết thêm chi tiết on the aeson issue tracker. Vấn đề đó cũng đề xuất thêm sử dụng toEncoding trên một loại khác với Value để đạt được điều này, nhưng không rõ liệu điều này có thực tế trong trường hợp của bạn hay không.

Các vấn đề liên quan