Спецификация формата ToJson по умолчанию, используемого Aeson

Кто-нибудь знает, где я могу найти документацию о том, как ADT переводятся в Json с помощью Aeson ToJSON? Я использую Haskell для внутреннего приложения и пытаюсь написать декодер JSON для другого функционального языка во внешнем интерфейсе, поэтому я хотел бы использовать тот же формат JSON, чтобы я мог отправлять сообщения между ними.


person jmite    schedule 15.01.2014    source источник


Ответы (2)


Я не думаю, что это очень хорошо задокументировано, но я добился большого успеха в подобных ситуациях, используя экземпляр QuickCheck Arbitrary для создания большого количества исходных типов, кодируя их в JSON, а затем используя их в качестве золотого стандарта. тесты для вашего интерфейса.

Вы также можете получить некоторое представление о том, как работает кодирование Aeson Template Haskell, заглянув по адресу настраиваемый Options введите Data.Aeson.TH. В частности, взгляните на SumEncoding, который позволит мне объяснить, например, что Either кодируется с использованием ObjectWithSingleField, то есть {"Left": 3} вместо Left 3.

person J. Abrahamson    schedule 15.01.2014

Конечно, просмотр кейсов, сгенерированных QuickCheck, — это своего рода практическое решение.

Но при размышлении удобно иметь некую концептуальную картину возможных вариантов перевода.

Я рассмотрел все доступные варианты перевода типов сумм в aeson и generic-aeson в ответе здесь, с Примеры.

Но особенность этого примера в том, что данные являются записями. Что-то может измениться в примерах, если это не так.

Итак, моя концептуальная картина (пожалуй, еще не полная и не совсем правильная) такова:

  • если тип не является нетривиальной суммой,

    • but is like a newtype (or has a single unary data constructor), this is simply a no-op in JSON.
    • Если это запись, она становится объектом.
    • Если это реальный, нетривиальный тип продукта (а не запись), то .... (наверное, массив).
  • есть специальные основные случаи: Maybe a, [a], различные String-подобные типы, Bool, Int-подобные, ...

  • если тип представляет собой нетривиальную сумму, то важно, является ли он «перечислением» (имеющим все нульарные конструкторы) или нет.

    • enums are translated into strings with the values;
    • non-enums according to a SumEncoding option:
      • whether it is a record or not may also make a difference (like in the first case of non-sums).

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

person imz -- Ivan Zakharyaschev    schedule 30.03.2015