Haskell 相当于 Python 的“Construct”

发布于 2024-07-30 05:41:48 字数 784 浏览 5 评论 0原文

Construct 是一种用 Python 实现的 DSL,用于描述数据结构(二进制和文本)。 一旦您描述了数据结构,construct 就可以为您解析和构建它。 哪一个好(“DRY”、“声明性”、“指称语义”...)

用法示例:

# 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),
    ),
  ),
)

我需要这样一个 Haskell 工具,并且 我想知道是否存在这样的事情。

我知道:

  • Data.Binary:用户单独实现解析和构建
  • Parsec:仅用于解析? 只适用于文字?

我想必须使用 Template Haskell 才能实现这一目标?

Construct is a DSL implemented in Python used to describe data structures (binary and textual). Once you have the data structure described, construct can parse and build it for you. Which is good ("DRY", "Declarative", "Denotational-Semantics"...)

Usage example:

# 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),
    ),
  ),
)

I am in need for such a tool for Haskell and
I wonder if something like this exists.

I know of:

  • Data.Binary: User implements parsing and building seperately
  • Parsec: Only for parsing? Only for text?

I guess one must use Template Haskell to achieve this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浪漫人生路 2024-08-06 05:41:48

目前(据我所知)Haskell 中没有相当于 Construct 的东西。

一种可以使用 Template Haskell 来实现。

Currently (afaik) there is no equivalent to Construct in Haskell.

One can be implemented using Template Haskell.

2024-08-06 05:41:48

我对 Python 或 Construct 一无所知,所以这可能不是您要寻找的内容,但对于简单的数据结构,您始终可以导出阅读:

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

现在,对于表达式

read "S 123" :: Test Double

GHCi 将发出:S 123.0

对于任何更复杂的东西,您可以使用 Parsec 创建一个 Read 实例。

I don't know anything about Python or Construct, so this is probably not what you are searching for, but for simple data structures you can always just derive read:

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

Now, for the expression

read "S 123" :: Test Double

GHCi will emit: S 123.0

For anything more complex, you can make an instance of Read using Parsec.

春风十里 2024-08-06 05:41:48

我想说这取决于您想要做什么,以及是否需要遵守任何现有格式。

Data.Binary 将(令人惊讶!)帮助您处理二进制数据,包括读取和写入。
您可以编写自己读/写的代码,也可以放弃细节并使用一些附加工具(例如 DrIFT派生。 DrIFT 作为预处理器工作,而 Derive 可以作为预处理器并与 TemplateHaskell 一起工作。

Parsec 只会帮助您解析文本。 没有二进制数据(同样容易),也没有写入。 工作是通过常规的String完成的。 hackage 上有 ByteString 等价物。

对于上面的示例,我将使用 Data.Binary 并自己编写自定义 put/geters。
查看 hackage 的解析器类别更多的选择。

I'd say it depends what you want to do, and if you need to comply with any existing format.

Data.Binary will (surprise!) help you with binary data, both reading and writing.
You can either write the code to read/write yourself, or let go of the details and generate the required code for your data structures using some additional tools like DrIFT or Derive. DrIFT works as a preprocessor, while Derive can work as a preprocessor and with TemplateHaskell.

Parsec will only help you with parsing text. No binary data (as easily), and no writing. Work is done with regular Strings. There are ByteString equivalents on hackage.

For your example above I'd use Data.Binary and write custom put/geters myself.
Have a look at the parser category at hackage for more options.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文