是否有模板haskell函数用于引用?

时间:2013-03-27 15:34:10

标签: haskell template-haskell

我在玩模板Haskell。我想创建一个准引号,它允许我为记录创建默认初始值设定项,例如

[record| data Config = { shouldDoX = True; featureY :: Integer, optionZ = Nothing } |]

应该创建一个函数

defaultConfig = Config { shouldDoX = True, optionZ = Nothing }

基本上它与数据声明的语法相同,默认值扩展。现在record是一个自定义的QuasiQuoter,但是我不想在其中解析表达式和类型。理想情况下,我只需将花括号内的块分成语句,并查找=::

所以我正在寻找一个与[e| ...|][t| ...|]引用相同的功能。我在Hoogle上搜索了一个函数String -> ExpQString -> Q Exp,但没有找到任何内容。

如果我不清楚我在寻找什么:我知道QuasiQuoters。正如我所提到的:record QuasiQuoter。现在,传递给我的准引号的字符串包含表达式(如Node 7 (Node 8 Nil Nil) Nil)和类型(如TrueMaybe (Either A B))。我可以自己解析这些,但我希望有一个函数可以为我做,就像我把字符串传递给像[e|...|]这样的引用。

所以:我正在寻找一个函数,我可以将表达式作为字符串或类型作为字符串提供,并返回足够的ExpType对象。我相信它必须存在于Q monad中,因为它应该根据上下文来评估表达式或类型(就像引用一样)。

functionOfMyDreams "Node 7 (Node 8 Nil Nil) Nil" :: Q Exp

2 个答案:

答案 0 :(得分:4)

我认为功能

parseExp :: String -> Either String Exp
parseType :: String -> Either String Type
来自haskell-src-meta包的

是你想要的。

http://hackage.haskell.org/package/haskell-src-meta-0.6.0.4/docs/Language-Haskell-Meta-Parse-Careful.html

这是一个quasiquoter的a self-contained example,可以使用haskell-src-meta反引用并嵌入Haskell表达式。

答案 1 :(得分:1)

你有正确的想法,但它会像String -> Q [Dec]

这样的功能

要创建一个quasiquoter,你必须创建一个QuasiQuoter类型的值,它有一个类型为String -> Q Blah的四个函数,其中Blah是你要拼接的Template Haskell类型。

在您的情况下,您只需要定义声明引号。

quoteRecord :: String -> Q [Dec]
quoteRecord = ...

record :: QuasiQuoter
record = QuasiQuoter (error "record is not a expression quoter")
                     (error "record is not a pattern quoter")
                     (error "record is not a type quoter")
                     quoteRecord

然后,您可以在另一个文件中使用您的记录准分析器

[record| ... |]

Haskell wiki

上有一个很好的演练

您也可以查看BNFC-meta,它会从语法中生成一个准分数。