【问题标题】:How to call the quasiquoter for haskell syntax explicitly?如何显式调用haskell语法的准引用器?
【发布时间】:2016-12-06 15:20:48
【问题描述】:

我正在 HaTeX 之上构建一个 eDSL。我面临的问题是我想在我的 LaTeX 文档中显示 Haskell 表达式,并且我想使用相同的 Haskell 表达式来帮助生成文档。

显而易见的答案是复制并粘贴表达式,以使其同时显示为引用和实时。我想避免这种情况,因为表达式可能会发生变化。

我想象的是一个准引用器,它既可以拼接它的内容,又可以输出一个表示它的字符串。

例如,我想输入以下内容:

document = do
    title "this is an example document"
    paragraph "This is normal text. We will now show the Haskell code that generates a table"
    [quoted| makeTable ["heading1","heading2"] ["cell1","cell2"] |]

我想把准引用扩展到:

document = do
    title "this is an example document"
    paragraph "This is normal text. We will now show the Haskell code that generates a table"
    makeTable ["heading1","heading2"] ["cell1","cell2"]
    listing Haskell "makeTable [\"heading1\",\"heading2\"] [\"cell1\",\"cell2\"]"

为此,我需要编写一个 QuasiQuoter:

quoted :: QuasiQuoter
quoted = QuasiQuoter
     { quoteExp = \str -> [e| $(_ str) >> listing Haskell $(lift str) |] }

我不确定用什么替换 $(_ str) 中的孔。我需要用 Haskell 表达式 quasi quoter 替换它,但我不确定如何调用它。如果ee :: QuasiQuoter,我可以用$(quoteExp e str) 填充这个洞,但不幸的是它不起作用。我应该填什么?

【问题讨论】:

    标签: haskell template-haskell


    【解决方案1】:

    简短的回答:没有简单的方法。 This question 仍然 没有出于某种原因没有得到答复。 String -> Q Exp Haskell 很难。最好的方法可能是通过haskell-src-meta 提供返回模板 Haskell AST 的解析器。特别是Language.Haskell.Meta.Parse 模块给了我们parseExp :: String -> Either String Exp

    import Language.Haskell.Meta.Parse (parseExp)
    
    quoted :: QuasiQuoter
    quoted = QuasiQuoter
         { quoteExp = \str ->
             case parseExp str of
               Left msg -> fail "Could not parse expression."
               Right exp -> [e| $(pure exp) >> listing Haskell $(liftString str) |] }
    

    【讨论】:

    • 太好了,谢谢!它似乎工作得非常好。我假设因为 parseExp 不在 Q monad 中,所以它可能无法很好地处理范围,但确实可以。包裹信息并未具体说明缺少的内容。你知道更多吗?
    • @simon1505475 是的,那个包裹需要一些爱。在底层它依赖于haskell-src-exts,它使您能够指定ParseModehaskell-src-meta 可能使用 defaultParseMode 在这种情况下“默认是未知文件名,没有扩展名(即 Haskell 98),不要忽略 LANGUAGE pragma,不要忽略 LINE pragma,并注意 Prelude 中的固定性。”
    • @simon1505475 我收回我之前的评论。 This is the parse mode used
    猜你喜欢
    • 2019-07-14
    • 2022-08-17
    • 1970-01-01
    • 2019-11-05
    • 2012-09-14
    • 2015-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多