Спецификация формата 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 опция:
      • является ли это записью или нет, также может иметь значение (как в первом случае не сумм).

Пожалуйста, исправьте меня или заполните недостающие пункты.

Другие вопросы по тегам