How to explicitly invoke a quasiquater for haskell syntax?

I am creating eDSL on top of HaTeX. The problem I am facing is that I want to display Haskell expressions in my LaTeX document, and I want to use the same Haskell expression to help generate the document.

The obvious answer is to copy and paste the expression so that it appears both in quotation marks and in real time. I want to avoid this because the expression can be changed.

What I represent is a quasi-cycle, which both splices its contents and outputs a string that represents it.

For example, here is what I would like to introduce:

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"] |]

and I would like the quasicart to expand to:

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\"]"

To do this, I need to write QuasiQuoter:

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

, $(_ str). Haskell, , . e e :: QuasiQuoter, $(quoteExp e str), , , . ?

+4
1

: . - - . 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) |] }
+5

Source: https://habr.com/ru/post/1662875/


All Articles