References:
Q
, the quotation monad, seems to be the main thing.
Q Dec
)
General:
import Language.Haskell.TH.Syntax
Lift
typeclass
derive Lift
possible with DeriveLift
ghc extension$name
$$name
unType :: TExp a -> Exp a
: Remove type info[|| ‥ ||]
(E: Expresssion, P: Pattern, L: Literal?, T: type?)
ExpQ is an alias for Q Exp
Example use:
Clash.Prelude Language.Haskell.TH> runQ [| \x -> 1 |]
LamE [VarP x_0] (LitE (IntegerL 1))
Clash.Prelude Language.Haskell.TH> :t it
it :: Language.Haskell.TH.Exp
Prelude> :set -XTemplateHaskell
Prelude> import Language.Haskell.TH.Syntax
Prelude Language.Haskell.TH.Syntax>
Non-type values can be quoted with one single quote:
Prelude Language.Haskell.TH.Syntax> :t 'id
'id :: Name
Prelude Language.Haskell.TH.Syntax> 'id
GHC.Base.id
Prelude Language.Haskell.TH.Syntax> :t id
id :: a -> a
Type values can be quoted with two single quotes:
Prelude Language.Haskell.TH.Syntax> ''Bool
GHC.Types.Bool
Prelude Language.Haskell.TH.Syntax> :t ''Bool
''Bool :: Name
Prelude Language.Haskell.TH.Syntax> 'Bool
<interactive>:31:1: error:
• Not in scope: data constructor ‘Bool’
• In the Template Haskell quotation 'Bool
Prelude Language.Haskell.TH.Syntax> :t LamE
LamE :: [Pat] -> Exp -> Exp
Prelude Language.Haskell.TH.Syntax> :t VarP
VarP :: Name -> Pat
The TemplateHaskell extension got to enable for some stuff to work:
Prelude Language.Haskell.TH.Syntax> runQ [e| Just x |]
<interactive>:20:18: error: parse error on input ‘]’
Prelude Language.Haskell.TH.Syntax> :set -XTemplateHaskell
Prelude Language.Haskell.TH.Syntax> runQ [e| Just x |]
AppE (ConE GHC.Maybe.Just) (UnboundVarE x)
varname is used in a top-level splice, quasi-quote, or annotation,
and must be imported, not defined locally
Last letter of variable names usually follow this convention:
[| ... |]
brackets are known as 'Oxford brackets'. It reifies haskell (ie, concrete haskell syntax -> AST)$( ... )
does the de-reification. In TH parlance, it's called splicing.
From https://markkarpov.com/tutorial/th.html:
Declaration | [d | ‥ | ] | Q [Dec] |
Expression | [e | ‥ | ] | Q Exp |
Typed expression | [ | ‥ | ||
Type | [t | ‥ | ] | Q Type |
Pattern | [p | ‥ | ] | Q Pat |
> import Language.Haskell.TH
λ> a = mkName "hi"
λ> :t a
λa :: Name