| Start |
|---|
| Syntax of Template Haskell and Quasiquotes Template Haskell is enabled by the SplicesExpression quotations (note: not a QuasiQuotation)
An expression quotation takes a compile time program and produces the AST represented by that program. The use of a value in a quotation (e.g. Typed splices and quotationsQuasiQuotesNames |
| The Q type The The compile-time environment includes:
The
Note that The TH library provides a function |
| An n-arity curry The familiar function can be generalized to tuples of arbitrary arity, for example: However, writing such functions for tuples of arity 2 to (e.g.) 20 by hand would be tedious (and ignoring the fact that the presence of 20 tuples in your program almost certainly signal design issues which should be fixed with records). We can use Template Haskell to produce such The First we produces fresh type variables for each of the arguments of the function - one for the input function, and one for each of the arguments to said function. The expression The function must build the argument tuple from the sequence of arguments, which is what
we've done here. Note the distinction between pattern variables ( Finally, the value which we produce is the AST We could have also written this function using quotations and 'lifted' constructors: Note that quotations must be syntactically valid, so Finally, we can load this TH function in GHCi: This example is adapted primarily from here (opens new window). RemarksWhat is Template Haskell?Template Haskell refers to the template meta-programming facilities built into GHC Haskell. The paper describing the original implementation can be found here (opens new window). What are stages? (Or, what is the stage restriction?)Stages refer to when code is executed. Normally, code is exectued only at runtime, but with Template Haskell, code can be executed at compile time. "Normal" code is stage 0 and compile-time code is stage 1. The stage restriction refers to the fact that a stage 0 program may not be executed at stage 1 - this would be equivalent to being able to run any regular program (not just meta-program) at compile time. By convention (and for the sake of implementation simplicity), code in the current module is always stage 0 and code imported from all other modules is stage 1. For this reason, only expressions from other modules may be spliced. Note that a stage 1 program is a stage 0 expression of type Futhermore, since splices can be nested, identifiers can have stages greater than 1. The stage restriction can then be generalized - a stage n program may not be executed in any stage m>n. For example, one can see references to such stages greater than 1 in certain error messages: Using Template Haskell causes not-in-scope errors from unrelated identifiers?Normally, all the declarations in a single Haskell module can be thought of as all being mutually recursive. In other words, every top-level declaration is in the scope of every other in a single module. When Template Haskell is enabled, the scoping rules change - the module is instead broken into groups of code seperated by TH splices, and each group is mutually recursive, and each group in the scope of all further groups. |
Read Article
https://develop.horje.com/learn/1434/reference