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

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

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

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

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

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

15
задан Matt Fenwick 17 September 2012 в 14:07
поделиться

5 ответов

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

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

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

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

5
ответ дан 1 December 2019 в 00:36
поделиться

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

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

3
ответ дан 1 December 2019 в 00:36
поделиться

Насколько я понимаю, самый простой способ сериализации и десериализации в Haskell - это унаследовать от Read и Show . Это просто и не соответствует вашим требованиям.

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

4
ответ дан 1 December 2019 в 00:36
поделиться

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

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

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

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

  • Для действительно необычных форматов сериализации - или для создания собственного пакета, подобного ранее упомянутым - можно достать самый большой молоток, своего рода «старшего брата» Читать и ] Показать : синтаксический анализ и красивая печать. Для обоих доступно множество пакетов, и, хотя поначалу это может показаться пугающим, синтаксический анализ и красивая печать на самом деле удивительно безболезненны в Haskell.

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

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

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

28
ответ дан 1 December 2019 в 00:36
поделиться

Вы хотели

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

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

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

Каждый пакет часто / обычно поставляется с макросом или механизмом деривации, позволяющим, например, получить JSON. Для Data.Binary, например, см. Этот предыдущий ответ: Term_to_binary Эрланга в Haskell?

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

5
ответ дан 1 December 2019 в 00:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: