Haskell中Python的“构造”对应是什么?

4 投票
3 回答
867 浏览
提问于 2025-04-15 13:21

Construct 是一个用 Python 实现的领域特定语言(DSL),主要用来描述数据结构(包括二进制和文本数据)。一旦你描述好了数据结构,Construct 就可以帮你解析和构建这些数据。这种方式有很多好处,比如避免重复(“DRY”)、声明式编程(“Declarative”)和明确的语义(“Denotational-Semantics”)等。

使用示例:

# 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 来实现这个吗?

3 个回答

-2

我对Python或Construct一点都不了解,所以这可能不是你想要的答案,但对于简单的数据结构,你可以直接使用读取的方法:

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

现在,对于这个表达式

read "S 123" :: Test Double

GHCi会输出:S 123.0

如果你想处理更复杂的情况,可以使用Parsec来创建一个Read的实例。

1

我觉得这要看你想做什么,以及你是否需要遵循某种现有的格式。

Data.Binary 可以帮助你处理二进制数据,包括读取和写入。你可以自己写代码来读取或写入数据,或者使用一些额外的工具,比如DrIFTDerive,让它们为你的数据结构生成所需的代码。DrIFT 是一个预处理器,而 Derive 可以作为预处理器,也可以与 TemplateHaskell 一起使用。

Parsec 只帮助你解析文本。它不太适合处理二进制数据,也不能写入数据。它主要处理普通的 String 字符串。在 hackage 上还有 ByteString 的对应版本。

对于你上面的例子,我会使用 Data.Binary,并自己写自定义的 putget 函数。你可以查看 hackage 上的解析器分类,了解更多选项。

0

目前(据我所知),在Haskell中没有和Construct相对应的东西。

不过,可以通过模板Haskell来实现一个类似的功能。

撰写回答