【发布时间】:2016-12-06 08:05:15
【问题描述】:
我正在尝试学习一些 Template Haskell 和 Quasi Quotation,我正在寻找一个接受 String 并将其解析为 Q Exp 的函数,因此类型为:
String -> Q Exp
尝试搜索 hoogle,但我看到的结果与将字符串文字提升到 Q Exp 有关,我发现最接近的是 Language.Haskell.TH.dyn,这完全符合我的要求,但仅适用于单个变量。
还有其他选择吗?例如。特殊语法?我只是在熟悉[||] 和$(),所以也许也有这个目的?
我想象的如何工作的一个例子:
runQ (parse "(1+)") == InfixE (Just (LitE (IntegerL 1))) (VarE GHC.Num.+) Nothing
另外,我知道这一点
runQ [| (1+) |] == InfixE (Just (LitE (IntegerL 1))) (VarE GHC.Num.+) Nothing
但这不适用于可变字符串,因为 - 可以理解 - 里面的字符串被视为文字。
runQ [| "(1+)" |] == LitE (StringL "(1+)")
编辑(2015-07-25):我已经开始使用haskell-src-meta,到目前为止它似乎运行良好。然而,cabal install 确实需要相当长的时间(在我的机器上大约需要 10 分钟)。真可惜,我的包实际上很小,我想安装是否可以快速。任何人都知道具有较小依赖性的解决方案?
【问题讨论】:
-
我相信haskell-src-meta 提供了这个
-
@luqui 我对那个包有点困惑。它在描述中写道“还没有 100% 完成”。 GHC 中不应该已经存在此功能吗?一定是,因为它需要
[|(1+)|],并且完全有能力将其转换为(InfixE _)。那么为什么需要一个可能正确解析也可能不正确解析的第三方包呢?还是我误解了,这也是 GHC 使用的规范代码?或者 GHC 可能根本没有公开这个功能?我将不胜感激。 :) -
AFAIU GHC 不公开此代码,但我不是 TH 专家
-
@luqui 如果是这样的话,在例如
Language.Haskell.TH.Parser.parse :: String -> Q Exp下公开它不是更优雅吗? -
如果 GHC 暴露它会方式更优雅,但它不能有那种类型。它需要一个包含所有可能影响解析的选项的类型。当它到达那里时,您最终会在
ghc和template-haskell包之间遇到循环依赖问题。