Спецификация формата ToJson по умолчанию, используемого Aeson
Кто-нибудь знает, где я могу найти документацию о том, как ADT переводятся в Json ToJSON Эзона? Я использую Haskell для внутреннего приложения и пытаюсь написать JSON-декодер для другого функционального языка внешнего интерфейса, поэтому я хотел бы использовать тот же формат JSON, чтобы я мог отправлять сообщения между ними.
2 ответа
Я не думаю, что это хорошо документировано, но я добился большого успеха в подобных ситуациях, используя QuickCheck Arbitrary
Например, генерировать большое количество типов источников, кодировать их в JSON, а затем использовать их в качестве золотого стандарта для тестирования внешнего интерфейса.
Вы также можете получить некоторую интуицию о том, как работает кодировка Aeson Template Haskell, заглянув в настраиваемыйOptions
введите Data.Aeson.TH
, В частности, посмотрите на SumEncoding
что позволит мне объяснить, например, что Either
кодируется с использованием ObjectWithSingleField
т.е. {"Left": 3}
за Left 3
,
Конечно, рассмотрение случаев, сгенерированных QuickCheck, является своего рода практическим решением.
Но, думая об этом, удобно иметь некоторую концептуальную картину возможных вариантов перевода.
Я просмотрел все доступные варианты перевода типов сумм в aeson
а также generic-aeson
в ответ здесь, с примерами.
Но специфика этого примера в том, что данные являются записями. Что-то может измениться в примерах, если это не так.
Итак, моя концептуальная картина (возможно, еще не полная и не совсем правильная) выглядит так:
если тип не является нетривиальной суммой,
- но, как новый тип (или имеет один унарный конструктор данных), это просто не работает в JSON.
- Если это запись, она становится объектом.
- Если это реальный, нетривиальный тип продукта (а не запись), то.... (возможно, массив).
Существуют особые основные случаи:
Maybe a
,[a]
, различныйString
-подобные типы,Bool
,Int
-лайк,...если тип является нетривиальной суммой, тогда важно, является ли это "enum" (имеющим все нулевые конструкторы) или нет.
- перечисления переводятся в строки со значениями;
- не перечисления в соответствии с
SumEncoding
опция:- является ли это записью или нет, также может иметь значение (как в первом случае не сумм).
Пожалуйста, исправьте меня или заполните недостающие пункты.