The implementation of a view on the \gls{DSL} is achieved by implementing the type classes with the data type representing the view.
In the case of our example \gls{DSL}, an interpreter accounting for failure may be implemented as an instance for the \haskellinline{Maybe} type.
-The standard infix functor application and infix sequential application are used so that potential failure is abstracted away from.\footnotemark{}
+The standard infix functor application and infix sequential application are used so that potential failure is abstracted away from\footnotemark.
\begin{lrbox}{\LstBox}
\begin{lstHaskell}[frame=]
<$> :: (a -> b) -> f a -> f b
\subsection{Adding semantics}
To add semantics to the \gls{DSL}, the existing classes are implemented with a novel data type representing the view on the \gls{DSL}.
-First a data type representing the semantics is defined. In this case, the printer is kept very simple for brevity and just defined as a \haskellinline{newtype} of a string to store the printed representation.\footnotemark{}
+First a data type representing the semantics is defined. In this case, the printer is kept very simple for brevity and just defined as a \haskellinline{newtype} of a string to store the printed representation\footnotemark.
\footnotetext{%
In this case a \haskellinline{newtype} is used instead of regular \haskellinline{data} declarations.
\haskellinline{newtype}s are special data types only consisting a single constructor with one field to which the type is isomorphic.
\end{lstHaskell}
The given \haskellinline{Printer} type is not sufficient to implement the instances for the \haskellinline{Function} class, it must be possible to generate fresh function names.
-After extending the \haskellinline{Printer} type to contain some sort of state to generate fresh function names and a \haskellinline{MonadWriter [String]}\footnotemark{} to streamline the output, we define an instance for every arity.
+After extending the \haskellinline{Printer} type to contain some sort of state to generate fresh function names and a \haskellinline{MonadWriter [String]}\footnotemark\ to streamline the output, we define an instance for every arity.
\begin{lrbox}{\LstBox}
\begin{lstHaskell}[frame=]
freshLabel :: Printer String
It is not possible to construct new values from expressions in the \gls{DSL}, to deconstruct a value into the fields, nor to test of which constructor the value is.
Furthermore, while in the our language the only constraint is the automatically derivable \haskellinline{Show}, in real-world languages the class constraints may be very difficult to satisfy for complex types, for example serialisation to a single stack cell in the case of a compiler.
-As a consequence, for user-defined data types---such as a pro\-gram\-mer-defined list type\footnotemark{}---to become first-class citizens in the \gls{DSL}, language constructs for constructors, deconstructors and constructor predicates must be defined.
+As a consequence, for user-defined data types---such as a pro\-gram\-mer-defined list type\footnotemark---to become first-class citizens in the \gls{DSL}, language constructs for constructors, deconstructors and constructor predicates must be defined.
Field selectors are also useful functions for working with user-defined data types, they are not considered for the sake of brevity but can be implemented using the deconstructor functions.
\footnotetext{
For example: \haskellinline{data List a = Nil \| Cons \{hd :: a, tl :: List a\}}
With the power of metaprogramming, we can generate the boilerplate code for our user-defined data types automatically at compile time.
To generate the code required for the \gls{DSL}, we define the \haskellinline{genDSL} function.
The type belonging to the name passed as an argument to this function is made available for the \gls{DSL} by generating the \haskellinline{typeDSL} class and view instances.
-For the \haskellinline{List} type it is called as: \haskellinline{\$(genDSL ''List)}.\footnotemark{}
+For the \haskellinline{List} type it is called as: \haskellinline{\$(genDSL ''List)}\footnotemark.
\footnotetext{
\haskellinline{''} is used instead of \haskellinline{'} to instruct the compiler to look up the information for \haskellinline{List} as a type and not as a constructor.
}
The \haskellinline{genDSL} function is a regular function---though \gls{TH} requires that it is defined in a separate module---that has type: \haskellinline{Name -> Q [Dec]}, i.e.\ given a name, it produces a list of declarations in the \haskellinline{Q} monad.
The \haskellinline{genDSL} function first reifies the name to retrieve the structural information.
-If the name matches a type constructor containing a data type declaration, the structure of the type---the type variables, the type name and information about the constructors\footnotemark{}---are passed to the \haskellinline{genDSL'} function.
+If the name matches a type constructor containing a data type declaration, the structure of the type---the type variables, the type name and information about the constructors\footnotemark---are passed to the \haskellinline{genDSL'} function.
\footnotetext{
Defined as \haskellinline{type VarBangType = (Name, Bang, Type)} by \gls{TH}.
}
The \haskellinline{getConsName} function filters out unsupported data types such as \glspl{GADT} and makes sure that every field has a name.
-For regular \glspl{ADT}, the \haskellinline{adtFieldName} function is used to generate a name for the constructor based on the indices of the fields\footnotemark{}.
+For regular \glspl{ADT}, the \haskellinline{adtFieldName} function is used to generate a name for the constructor based on the indices of the fields\footnotemark.
\footnotetext{
\haskellinline{adtFieldName :: Name -> Integer -> Name}
}
Therefore, the constructor function can be implemented by lifting the actual constructor to the \haskellinline{Maybe} type using sequential application.
I.e.\ for a constructor $C_k$ this results in the following constructor: \haskellinline{ck a0 ... am = pure Ck <*> a0 <*> ... <*> am}.
To avoid accidental shadowing, fresh names for all the arguments are generated.
-The \haskellinline{ifx} function is used as a shorthand for defining infix expressions.\footnotemark{}
+The \haskellinline{ifx} function is used as a shorthand for defining infix expressions\footnotemark.
\begin{lrbox}{\LstBox}
\begin{lstHaskell}[frame=]
ifx :: String -> Q Exp -> Q Exp -> Q Exp
To avoid accidental shadowing first fresh names for the arguments and fields are generated.
Then, a function is created with the two arguments.
First \haskellinline{d} is evaluated and bound to a host language function that deconstructs the constructor and passes the fields to \haskellinline{f}.
-I.e.\ a deconstructor function $C_k$ is defined as: \haskellinline{unCk d f = d >>= \\(Ck a0 .. am)->f (pure a0) ... (pure am))}.\footnotemark{}
+I.e.\ a deconstructor function $C_k$ is defined as: \haskellinline{unCk d f = d >>= \\(Ck a0 .. am)->f (pure a0) ... (pure am))}\footnotemark.
\footnotetext{
The \haskellinline{nameBase :: Name -> String} function from the \gls{TH} library is used to convert a name to a string.
}
\section{Pattern matching}
It is possible to construct and deconstruct values from other \gls{DSL} expressions, and to perform tests on the constructor but with a clunky and unwieldy syntax.
They have become first-class citizens in a grotesque way.
-For example, given that we have some language constructs to denote failure and conditionals\footnotemark{}, writing a list summation function in our \gls{DSL} would be done as follows.
+For example, given that we have some language constructs to denote failure and conditionals\footnotemark, writing a list summation function in our \gls{DSL} would be done as follows.
For the sake of the argument we take a little shortcut here and assume that the interpretation of the \gls{DSL} supports lazy evaluation by using the host language as a metaprogramming language as well, allowing us to use functions in the host language to contstruct expressions in the \gls{DSL}.
\begin{lrbox}{\LstBox}