scr*_*avy 10 haskell template-haskell
我正在玩模板Haskell.我想创建一个准引号,它允许我为记录创建默认初始值设定项,例如
[record| data Config = { shouldDoX = True; featureY :: Integer, optionZ = Nothing } |]
Run Code Online (Sandbox Code Playgroud)
应该创建一个功能
defaultConfig = Config { shouldDoX = True, optionZ = Nothing }
Run Code Online (Sandbox Code Playgroud)
基本上它与数据声明的语法相同,默认值扩展.现在record是一个自定义QuasiQuoter,但是有些表达式和类型我不想解析自己.理想情况下,我只需要将花括号内的块分成语句并查找=和::.
所以我正在寻找一个有效的功能与引用[e| ...|]或相同的功能[t| ...|].我搜索过Hoogle的功能String -> ExpQ,String -> Q Exp但没有找到任何东西.
如果我不清楚我在寻找什么:我知道QuasiQuoters.正如我所提到的:record 是 QuasiQuoter.现在传递给我的准引号的字符串包含表达式(如Node 7 (Node 8 Nil Nil) Nil)和类型(如True或Maybe (Either A B)).我可以自己解析这些,但我希望有一个函数可以为我做,就像我把字符串传递给像这样的引号[e|...|].
所以:我正在寻找一个函数,我可以将表达式作为String,或者Type作为String,并返回适当的Exp或Type对象.我相信它必须存在于Q monad中,因为它应该根据上下文来评估表达式或类型(就像引用一样).
functionOfMyDreams "Node 7 (Node 8 Nil Nil) Nil" :: Q Exp
Run Code Online (Sandbox Code Playgroud)
你的想法是正确的,但它会是一个像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
Run Code Online (Sandbox Code Playgroud)
然后您可以在另一个文件中使用您的记录准引用
[record| ... |]
Run Code Online (Sandbox Code Playgroud)
Haskell wiki上有一个很好的演练
您可能还想查看BNFC-meta,它将根据语法生成准引用符。
| 归档时间: |
|
| 查看次数: |
479 次 |
| 最近记录: |