gpt4 book ai didi

haskell - 在 Haskell 编译期间如何在不同位置包含代码?

转载 作者:行者123 更新时间:2023-12-01 01:19:58 26 4
gpt4 key购买 nike

Quasi-quotes 允许在编译期间生成 AST 代码,但它会在 Quasi-quote 的编写位置插入生成的代码。是否可以以任何方式将编译时生成的代码插入其他地方?例如,在特定的模块文件中,与编写 QQ 的模块文件不同?这将取决于硬编码的模块结构,但这很好。

如果 QQ 无法做到这一点,但任何人都知道实现它的不同方式,我愿意提供建议。

最佳答案

要回答这个问题,了解什么是准报价者会很有帮助。来自 GHC Documentation , 准报价者是

data QuasiQuoter = QuasiQuoter { quoteExp  :: String -> Q Exp,
quotePat :: String -> Q Pat,
quoteType :: String -> Q Type,
quoteDec :: String -> Q [Dec] }

也就是说,它是从任意字符串到 ExpQ 中的一个或多个的解析器。 , PatQ , TypeQ , 和 DecQ ,它们分别是表达式、模式、类型和声明的模板 Haskell 表示。

当您使用准引号时,GHC 将解析器应用于字符串以创建 ExpQ (或其他类型),然后拼接生成的模板 haskell 表达式以产生实际值。

听起来您要求做的是将准引号解析和拼接分开,以便您可以访问 TH 表达式。然后你可以将该表达式导入另一个模块并自己在那里拼接。

知道准报价者的类型,很明显这是可能的。通常你使用QQ作为
-- file Expr.hs
eval :: Expr -> Integer
expr = QuasiQuoter { quoteExp = parseExprExp, quotePat = parseExprPat }

-- file Foo.hs
import Expr
myInt = eval [expr|1 + 2|]

相反,您可以自己提取解析器,获取 TH 表达式,然后再拼接:
-- file Foo.hs
import Expr

-- run the QQ parser
myInt_TH :: ExpQ
myInt_TH = quoteExp expr "1 + 2"

-- file Bar.hs
import Foo.hs

-- run the TH splice
myInt = $(myInt_TH)

当然,如果您自己编写所有这些,您可以跳过准引号并直接使用解析器和模板 Haskell。无论哪种方式,这几乎都是一样的。

关于haskell - 在 Haskell 编译期间如何在不同位置包含代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10020521/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com