Подтвердить что ты не робот

Как сделать автоматическую сериализацию данных объектов данных?

Одним из огромных преимуществ на языках, которые имеют какое-то отражение/интроспекцию, является то, что объекты могут быть автоматически построены из разных источников.

Например, в Java я могу использовать те же объекты для сохранения в db (с Hibernate), сериализации в XML (с JAXB) и сериализации в JSON (json-lib). Вы можете сделать то же самое в Ruby и Python, как правило, следуя некоторым простым правилам для свойств или аннотаций для Java.

Таким образом, мне не нужно много "объектов переноса домена". Я могу сосредоточиться на домене, в котором я работаю.

Кажется, что в очень строгом FP, таком как Haskell и Ocaml, это невозможно. Особенно Хаскелл. Единственное, что я видел, это сделать некоторую предварительную обработку или метапрограммирование (ocaml). Принято ли вам, что вы должны делать все преобразования снизу вверх?

Другими словами, вам нужно сделать много скучной работы, чтобы превратить тип данных в haskell в объект JSON/XML/DB Row и снова вернуться в объект данных.

4b9b3361

Ответ 1

Для чего это стоит, я думаю, что предустановленное решение, найденное в OCaml (как показано на примере sexplib, binprot и json-wheel среди других), довольно велико (и я думаю, что люди делают очень похожие вещи с Template Haskell). Это намного эффективнее, чем отражение, и также может быть настроено на отдельные типы естественным образом. Если вам не нравится автоматический сгенерированный сериализатор для данного типа foo, вы всегда можете просто написать свой собственный, и он прекрасно вписывается в автоматически генерируемые сериализаторы для типов, которые включают foo в качестве компонента.

Единственным недостатком является то, что вам нужно изучить camlp4, чтобы написать один из них для себя. Но использовать их довольно просто, как только вы получите свою систему сборки, чтобы использовать препроцессор. Это так же просто, как добавление with sexp в конец определения типа:

type t = { foo: int; bar: float }
with sexp

и теперь у вас есть ваш сериализатор.

Ответ 2

Я не могу говорить с OCaml, но я бы сказал, что главная трудность в Haskell заключается в том, что десериализация требует знания типа заранее - нет универсального способа механического десериализации из формата, выяснить, каково результирующее значение, и перейти оттуда, как это возможно на языках с необоснованными или динамическими типами систем.

Отмечая проблему типа, существуют различные подходы к сериализации данных в Haskell:

  • Встраиваемые классы классов Read/Show (de) сериализуют алгебраические типы данных и большинство встроенных типов в виде строк. Показатели с хорошими результатами обычно должны быть такими, что read . show эквивалентно id и что результат Show может быть проанализирован как исходный код Haskell, построивший сериализованное значение.

  • Различные пакеты сериализации можно найти в Hackage; обычно они требуют, чтобы тип, который должен быть сериализован, был экземпляром какого-либо типа класса, причем пакет обеспечивал экземпляры для большинства встроенных типов. Иногда они просто требуют автоматически выводимого экземпляра типа-reifying, отражающего метапрограммирования класса Data (очаровательное полное имя, для которого есть Data.Data.Data), или предоставляют код шаблона Haskell для автоматического генерации экземпляров.

    /li >
  • Для действительно необычных форматов сериализации - или для создания своего собственного пакета, такого как ранее упомянутые, - можно достичь самого большого доступного молотка, своего рода "старшего брата" до Read и Show: синтаксический анализ и печать. Многочисленные пакеты доступны для обоих, и, хотя сначала может показаться пугающим, синтаксический анализ и довольно-печатная версия на самом деле удивительно безболезненны в Haskell.

Взгляд на Hackage показывает, что пакеты сериализации уже существуют для различных форматов, включая двоичные данные, JSON, YAML и XML, хотя я не использовал ни одного из них, поэтому я не могу лично подтвердить, насколько хорошо они работают. Здесь вы найдете исчерпывающий список, чтобы вы начали:

  • binary: ориентированная на производительность сериализация на ленивый ByteString s
  • cereal: похоже на двоичный, но немного отличающийся интерфейс и использует строгий ByteString s
  • genericserialize: Сериализация с помощью встроенного метапрограммирования, формат вывода расширяемый, включает в себя вывод sex-выхода R5RS.
  • json: облегченная сериализация данных JSON
  • RJson: Сериализация в JSON через встроенное метапрограммирование
  • hexpat-pickle: Комбинаторы для сериализации в XML, используя пакет "hexpat"
  • regular-xmlpickler: Сериализация в XML рекурсивных структур данных с использованием "обычного" пакета

Единственная другая проблема заключается в том, что неизбежно не все типы будут сериализованы - если не что иное, я подозреваю, что вам будет сложно сериализовать полиморфные типы, экзистенциальные типы и функции.

Ответ 3

Я понимаю, что самый простой способ сериализации и десериализации в Haskell состоит в том, чтобы вывести из Read и Show. Это просто и не заполняет ваши требования.

Однако есть HXT и Text.JSON, которые, как представляется, обеспечивают то, что вам нужно.

Ответ 4

сделать много скучной работы, чтобы превратить тип данных в haskell в объект JSON/XML/DB Row и обратно в объект данных.

В Haskell существует множество способов сериализации и нессериализации типов данных. Вы можете использовать, например,

а также другие распространенные форманты (протокольные буферы, thrift, xml)

Каждый пакет часто/обычно поставляется с механизмом макроса или вывода, который позволяет вам, например, вывести JSON. Например, для Data.Binary см. Предыдущий ответ: term_to_binary Erlang в Haskell?

Общий ответ: у нас есть много замечательных пакетов для серализации в Haskell, и мы склонны использовать существующую инфраструктуру существующего класса (с помощью макросов для генерации или шаблона haskell для фактического вывода).

Ответ 5

Обычный подход заключается в использовании Data.Binary. Это обеспечивает базовую возможность сериализации. Двоичные экземпляры для типов данных просты в записи и могут быть легко построены из меньших единиц.

Если вы хотите автоматически генерировать экземпляры, вы можете использовать Template Haskell. Я не знаю ни одного пакета, чтобы сделать это, но я не удивлюсь, если он уже существует.