Хаскелловский эквивалент "конструкции питона"


Construct - это DSL, реализованный в Python, используемый для описания структур данных (двоичных и текстовых). После того, как вы описали структуру данных, construct может проанализировать и построить ее для вас. Что хорошо ("сухо", "декларативно", "Денотационно-семантически"...)

Пример использования:

# code from construct.formats.graphics.png
itxt_info = Struct("itxt_info",
  CString("keyword"),
  UBInt8("compression_flag"),
  compression_method,
  CString("language_tag"),
  CString("translated_keyword"),
  OnDemand(
    Field("text",
      lambda ctx: ctx._.length - (len(ctx.keyword) + 
      len(ctx.language_tag) + len(ctx.translated_keyword) + 5),
    ),
  ),
)

Я нуждаюсь в таком инструменте для Хаскелла и Интересно, существует ли нечто подобное?

Я знаю о:

  • данные.Binary: пользователь реализует синтаксический анализ и построение отдельно
  • Parsec: только для разбора? Только для текста?

Я полагаю, что для этого нужно использовать шаблон Haskell?

3 3

3 ответа:

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

Данные.Бинарная воля (сюрприз!) поможет вам с двоичными данными, как для чтения, так и для записи. Вы можете либо написать код для чтения / записи самостоятельно, либо отпустить детали и сгенерировать необходимый код для ваших структур данных, используя некоторые дополнительные инструменты, такие как DrIFT или Derive. Дрифт работает как препроцессор, а извлечь могут работать в качестве препроцессора и с TemplateHaskell.

Parsec поможет вам только с разбором текста. Никаких двоичных данных (так же легко) и никакой записи. Работа выполняется с регулярными Strings.существуют ByteString эквиваленты на хакаже.

Для вашего примера выше я бы использовал данные.Бинарные и пользовательские записиput/getи я тоже. Посмотрите на категорию парсера в hackage для получения дополнительных опций.

Я ничего не знаю о Python или Construct, так что это, вероятно, не то, что вы ищете, но для простых структур данных вы всегда можете просто вывести read:

data Test a = I Int | S a deriving (Read,Show)

Теперь для выражения

read "S 123" :: Test Double

GHCi будет излучать: S 123.0

Для чего-либо более сложного вы можете создать экземпляр Read, используя Parsec.

В настоящее время (afaik) нет эквивалента конструкции в Haskell.

Можно реализовать с помощью шаблона Haskell.