Как явно назвать квазиквотер для синтаксиса haskell?
Я строю eDSL поверх HaTeX. Проблема, с которой я сталкиваюсь, заключается в том, что я хочу отобразить выражения Haskell в своем документе LaTeX и использовать то же выражение 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, но я не знаю, как его назвать. Если e
было e :: QuasiQuoter
Я мог бы заполнить дыру $(quoteExp e str)
но это, к сожалению, не работает. Чем мне его заполнить?
1 ответ
Краткий ответ: нет простого пути. Этот вопрос до сих пор остался без ответа по причине. String -> Q Exp
для Хаскелла это сложно. Лучший способ, вероятно, через 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) |] }