This text is a translation of the Template Haskell documentation written by Bulat Ziganshin. Translation of the entire text is divided into several logical parts to facilitate perception. Further italics in the text - notes of the translator.
yell file line = fail ($(printf "Error in file %s line %d") file line)  yell file line = fail ((\x1 x2 -> "Error in file "++x1++" line "++show x2) file line)  data T = A Int String | B Integer | C $(deriveShow ''T)  data T = A Int String | B Integer | C instance Show T show (A x1 x2) = "A "++show x1++" "++show x2 show (B x1) = "B "++show x1 show C = "C" Exp type for expressions, Pat for samples, Lit for literals, Dec for declarations, Type for types, etc. Definitions of all these types can be found in the documentation for the Language.Haskell.TH.Syntax module. They are interconnected according to Haskell syntax rules, so using them you can construct values ββrepresenting any Haskell code fragments. Here are some simple examples: varx = VarE (mkName "x") represents the expression x , i.e. simple variable β x β patx = VarP (mkName "x") represents sample x , i.e. the same variable β x β used in the sample str = LitE (StringL "str") represents the constant expression "str" tuple = TupE [varx, str] represents a pair expression (tuple) (x,"str") LamE [patx] tuple represents the lambda expression \x -> (x,"str")Exp type constructors end with E , the names of Pat -type constructors end with P , etc. The mkName function used above creates a value of type Name (representing identifiers) from a normal string ( String ), with its contents as a name.Exp (you can also use Dec , Pat or Type ) , which is a representation for a given code fragment. In fact, you do not need to thoroughly study the device of these types in order to know how to submit the Haskell code you need into them. In the section on debugging, I will tell you how to get a TH-representation of a specific Haskell code fragment.Exp . Instead, they are calculations in a special Q monad (called the qadtation monad citation monad), which allows you to automatically generate unique names for variables using the monadic function newName :: String -> Q Name . Each time it is called, a new unique name is generated with the given prefix. This name can be used as part of a pattern (using the constructor VarP :: Name -> Pat ) or an expression ( VarE :: Name -> Exp ).tupleReplicate template, which, when used as follows: β$(tupleReplicate n) x" , returns an n-tuple with x at all positions (similar to the replicate function for lists). Note that n Is the template argument, and x is the argument of the generated anonymous function (lambda expression). I provide the code for the module containing the definition of this template (the Language.Haskell.TH module provides all the tools needed for working with TH): module TupleReplicate where import Language.Haskell.TH tupleReplicate :: Int -> Q Exp tupleReplicate n = do id <- newName "x" return $ LamE [VarP id] (TupE $ replicate n $ VarE id) tupleReplicate 3 β will return an Exp value equivalent to the Haskell expression β (\x -> (x,x,x)) β.$x β, where x is an identifier, or in the form of $(...) , where the ellipsis implies the corresponding expression. It is important that there is no space between the $ character and the identifier or brackets. This use of $ overrides the value of this symbol as an infix operator, as well as the qualified name Mx overrides the value of the function composition operator β . ". If you need an operator, then the character must be surrounded by spaces.Q Exp .Q [Dec] . Ads generated by the insert have access only to those identifiers that were previously declared in the code (which is not typical of regular Haskell programs, in which the order of ads does not matter).Q Type .-XTemplateHakell flag to enable the special TH syntax; or you can include the directive {-# LANGUAGE TemplateHaskell #-} in the source code.tupleReplicate template: {-# LANGUAGE TemplateHaskell #-} module Test where import TupleReplicate main = do print ($(tupleReplicate 2) 1) --  (1,1) print ($(tupleReplicate 5) "x") --  ("x","x","x","x","x") printf and deriveShow mentioned at the beginning are deriveShow .Source: https://habr.com/ru/post/131998/
All Articles