Haskell中Python的“构造”对应是什么?
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 个回答
我对Python或Construct一点都不了解,所以这可能不是你想要的答案,但对于简单的数据结构,你可以直接使用读取的方法:
data Test a = I Int | S a deriving (Read,Show)
现在,对于这个表达式
read "S 123" :: Test Double
GHCi会输出:S 123.0
如果你想处理更复杂的情况,可以使用Parsec来创建一个Read的实例。
我觉得这要看你想做什么,以及你是否需要遵循某种现有的格式。
Data.Binary 可以帮助你处理二进制数据,包括读取和写入。你可以自己写代码来读取或写入数据,或者使用一些额外的工具,比如DrIFT 或 Derive,让它们为你的数据结构生成所需的代码。DrIFT 是一个预处理器,而 Derive 可以作为预处理器,也可以与 TemplateHaskell 一起使用。
Parsec 只帮助你解析文本。它不太适合处理二进制数据,也不能写入数据。它主要处理普通的 String
字符串。在 hackage 上还有 ByteString
的对应版本。
对于你上面的例子,我会使用 Data.Binary,并自己写自定义的 put
和 get
函数。你可以查看 hackage 上的解析器分类,了解更多选项。
目前(据我所知),在Haskell中没有和Construct相对应的东西。
不过,可以通过模板Haskell来实现一个类似的功能。