\documentclass[11pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{graphicx}
%\usepackage{cite}
%\usepackage{wrapfig}
%\usepackage[left=2cm,right=2cm,top=2cm,bottom=2cm]{geometry}

\title{Lecture 8: Atmospheric Stability}
\author{}

\begin{document}
\maketitle
\section*{Overview}

We determine the variation of density, pressure, and temperature with height in the Earth's atmosphere. Using the temperature gradient, we can classify the atmosphere as stable or unstable to vertical motions.

\section{Pressure variation}
Due to gravity, we expect the density of air to decrease as we go higher up in the atmosphere. We want to determine the characterstic height at which density or pressure fall to $1/e$ of their surface values. Assuming the atmosphere to be thin (height of atmosphere $\ll$ diamter of the Earth) and temperature to be constant through the domain, we can write
\begin{align*}
\frac{dp}{dz} = \rho_a (-g)
\end{align*}

where $p$ is the pressure, $z$ is the vertical height measured from ground and $\rho_a$ is density of the air. Using the ideal gas equation of state $p=\rho_a \hat{R}_a T$, we get
\begin{align*}
\frac{dp}{dz} &= \frac{p(-g)}{\hat{R}_a T} \\
\Rightarrow p &= p_0 e^{-gz/\hat{R}_a T}
\end{align*}

This gives the pressure variation with height. The characterstic length scale for this variation is $\frac{\hat{R}_a T}{g}$. Note that $\hat{R}_a$ is defined per unit mass. Taking $T=300K$, we get the characterstic height as $\sim 8.4$ km . Therefore, pressure and density drop to $1/e$ of their surface value at about 8.4 km above Earth's surfce.

\section{Temperature variation}
Pressure and density decrease exponentially under these assumptions. Even if these are relaxed, their variation is at least monotonic. But temperature varation is not monotonic throughout the atmosphere. We can though, derive an expression for the temperature variation in the Troposphere. In order to derive the temperature variation, we will consider a Lapse-Rate Atmosphere. A Lapse-Rate Atmosphere is a hypothetical neutral object that seperates stable and unstable atmosphere.

Stability of the atmosphere, in this context, refers to its susceptibility to vertical motions. Basically, we want to know the fate of a (vertically) displaced parcel of fluid. If a parcel displaced upwards experiences buoyancy and continues to go upwards, then the atmosphere is unstable. If it falls back, then the atmosphere is stable. Lapse-Rate Atmosphere is the hypothetical neutral configuration between the two.

Our objective is to calculate the temperature gradient of the Lapse-Rate Atmosphere or, in other words, the rate of change of temperature of a parcel of air when it is vertically displaced in a Lapse-Rate Atmosphere. Note that a neutrally stable atmosphere does not have a uniform temperature throughout because of the pressure variation.
\subsection{Dry Adiabatic Lapse Rate}
We assume the process of the parcel rising through the atmosphere to be reversible and adiabatic. Then using the first law of thermodynamics, with $\delta q=0$, we get
\begin{align*}
de = -\delta W = -p dV
\end{align*}

This tells us that work is done at the expense of internal energy. For ideal gas, $e\equiv e(T)$. Therefore, as a parcel rises and moves into a lower pressure region, it expands and does work. This work causes reduction in the internal energy and hence temperature drops as the parcel rises up. Further assuming air to be calorically perfect ($C_p$ and $C_v$ are independent of T), and using the adiabatic expansion relation $p \propto \rho^{\gamma}$ gives us the result
\begin{align*}
\frac{dT}{dz} = \frac{-g}{C_p}
\end{align*}

This comes out to be nearly $10 K/Km$. Hence temperature of the parcel falls by about $10K$ for each $1 Km$ rise in height. This is called the Dry Adiabatic Lapse Rate (DALR). Dry - because we haven't yet considered the effect of water vapour present in the air parcel.

\subsection{Moist Adiabatic Lapse Rate}

In order to incorporate the effect of vapour, note that the parcel is rising into a region of lower pressure and temperature. Water tends to evaporate at low pressure and condense at low temperature. If it so happens that the fall in temperature overcompensates the effect of fall in pressure, then water will condense. This condensation will cause the release of latent heat of vaporization which will heat the air parcel. Therefore, the net cooling of the air parcel will be less than $10K/Km$ (usually varies between $4 - 9 K/Km$). This is called the Moist Adiabatic Lapse Rate (MALR). Once all the water inside the parcel condenses, the rate of cooling again approaches DALR.

In order to derive an expression for it, we proceed as for the DALR, but now $\delta q \neq 0$. The parcel is getting heated due to the latent heat and therefore, $\delta q = -L dW_v$. Here $dW_v$ is the mass of water-vapour per unit mass of air and $L$ is the latent heat of water per unit mass. The negative sign denotes that it is decreasing with height. With this modification, we get the MALR as
\begin{align*}
\frac{dT}{dz} &= \frac{-g/C_p}{1+\frac{L}{C_v}\frac{dW_v}{dT}}\\
\end{align*}

This expression differs from the DALR only if $\frac{dW_v}{dT}$ is non-zero i.e. after the parcel becomes saturated and there is condensation. If $dT$ is more, then parcel can hold more vapour and hence $\frac{dW_v}{dT} > 0$. Therefore,
\begin{align*}
|MALR| &<|DALR|
\end{align*}

As parcel rises, the partial pressure of water vapour\footnote{Fraction of total pressure that is being exerted by the vapour molecules} decreases. Also the temperature, and hence the vapour pressure\footnote{Pressure required to condense the vapour molecules at a given temperature} decreases. But the vapour pressure decreases faster than the partial pressure and the parcel invariably becomes saturated.

\section{Atmospheric stability}

We know that the cooling rate of an unsaturated parcel is DALR. If the atmospheric cooling rate is faster than this, then a raised parcel will find itself in a cooler environment and will continue to rise. Therefore if atmospheric cooling rate is faster than DALR, then it's unstable. Similarly we can see that if the atmospheric cooling rate is slower than DALR then it's stable and atmosphere is neutral if they are equal.

\subsection{Conditional Stability}

Suppose the cooling rate of atmosphere is slower than DALR but more than MALR. Since it is slower than DALR, the atmosphere appears to be stable (as discussed before). But if due to some mechanism, an air parcel gets kicked high enough so that it becomes satured and the vapour inside it begins to condense, then the effective cooling rate becomes MALR. Now, the cooling rate of the parcel is slower than cooling rate of atmosphere. So an upward displaced parcel will find itself in a warmer environment and will continue to rise.

\section{Appendix}
\subsection{Derivation for DALR}
\subsection{Derivation for MALR}
\subsection{Equation of state for water vapour}
Starting with the Gibbs-Duhem equation applied at the phase boundary between water and water vapour
\begin{align*}
&(\nu dp - s dT) = d\mu \\
\Rightarrow &(\nu dp - s dT)_l = (\nu dp - s dT)_g \\
\Rightarrow &\frac{dP_{v}}{dT} = \frac{s_v - s_l}{\nu_v} \quad \quad \quad \text{\footnotesize{$(\nu_l \ll \nu_v)$}} \\
\Rightarrow &\frac{dP_{v}}{dT} = \frac{T(s_v - s_l)}{T \nu_v} \\
\Rightarrow &\frac{dP_{v}}{dT} = \frac{L \rho_v}{T} \quad \quad (T\Delta s = L, 1/nu_v = \rho_v) \\
\end{align*}
Using ideal gas equation,
\begin{align*}
\Rightarrow &\frac{dP_{v}}{dT} = -\frac{L p_v}{\hat{R}_v T}
\end{align*}
which finally gives,
\begin{align*}
p_v(T) = A e^{\frac{-L}{\hat{R}_v T}}
\end{align*}

This is the equation of state for water vapour.

\subsection{Layers of the atmosphere}
\begin{itemize}
\item Troposphere - upto $\sim$ 12 km
\item Stratosphere - (15 - 50 Km)
\item Mesosphere - (50 - 80 Km)
\item Thermosphere - (80 - 700 Km)
\item Exosphere - 700 Km and upwards
\end{itemize}

\end{document}


%-----------------------------------------------------------------------------
%
%               Template for sigplanconf LaTeX Class
%
% Name:         sigplanconf-template.tex
%
% Purpose:      A template for sigplanconf.cls, which is a LaTeX 2e class
%               file for SIGPLAN conference proceedings.
%
% Guide:        Refer to "Author's Guide to the ACM SIGPLAN Class,"
%               sigplanconf-guide.pdf
%
% Author:       Paul C. Anagnostopoulos
%               Windfall Software
%               978 371-2316
%               paul@windfall.com
%
% Created:      15 February 2005
%
%-----------------------------------------------------------------------------

\documentclass[preprint]{sigplanconf}

% The following \documentclass options may be useful:

% preprint      Remove this option only once the paper is in final form.
% 10pt          To set in 10-point type instead of 9-point.
% 11pt          To set in 11-point type instead of 9-point.
% numbers       To obtain numeric citation style instead of author/year.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\usepackage{amsmath,amsfonts}
\usepackage{hyperref}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\usepackage{amsthm}
\makeatletter
\def\th@definition{%
  \thm@notefont{}% same as heading font
  \normalfont % body font
}
\makeatother
\theoremstyle{definition}
\newtheorem{problem}{Problem}
\newtheorem{defn}{Definition}
\newtheorem{note}{Note}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\usepackage{courier}
%\usepackage{pxfonts}
\usepackage{listings}
\lstset{
    %language=Haskell,
    basicstyle=\ttfamily\footnotesize,
    keywordstyle=\bfseries\ttfamily\footnotesize,
    showstringspaces=false,
    %morekeywords={class,data,type,family,instance, where, ghci},
    morekeywords={ghci},
    %basicstyle=\footnotesize,
    literate={->}{{$\rightarrow$}}2 {>=}{{$\geq$}}2 {<-}{{$\leftarrow$}}2
             {<=}{{$\leq$}}2 {=>}{{$\Rightarrow$}}2
             {~}{\tiny{$\sim$}}1
    %keywordstyle=\lst@ifdisplaystyle\color{blue}\fi,
    %commentstyle=\color{gray}
}
\lstMakeShortInline|

\newcommand{\cL}{{\cal L}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcommand{\homoiconic}{{\ttfamily homoiconic}~}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{filecontents}{paper.bib}
@article{birkhoff1970heterogeneous,
  title={Heterogeneous algebras},
  author={Birkhoff, Garrett and Lipson, John D},
  journal={Journal of Combinatorial Theory},
  volume={8},
  number={1},
  pages={115--133},
  year={1970},
  publisher={Elsevier}
}

@article{goldberg1991,
  title={What every computer scientist should know about floating-point arithmetic},
  author={Goldberg, David},
  journal={ACM Computing Surveys (CSUR)},
  volume={23},
  number={1},
  pages={5--48},
  year={1991},
  publisher={ACM}
}

@inproceedings{jones2001playing,
  title={Playing by the rules: rewriting as a practical optimisation technique in GHC},
  author={Jones, Simon Peyton and Tolmach, Andrew and Hoare, Tony},
  booktitle={Haskell workshop},
  volume={1},
  pages={203--233},
  year={2001}
}

@book{higham2002,
  title={Accuracy and stability of numerical algorithms},
  author={Higham, Nicholas J},
  year={2002},
  publisher={Siam}
}

@inproceedings{sheard2002template,
  title={Template meta-programming for Haskell},
  author={Sheard, Tim and Jones, Simon Peyton},
  booktitle={Proceedings of the 2002 ACM SIGPLAN workshop on Haskell},
  pages={1--16},
  year={2002},
  organization={ACM}
}

@article{swierstra2008,
  title={Data types {\`a} la carte},
  author={Swierstra, Wouter},
  journal={Journal of functional programming},
  volume={18},
  number={04},
  pages={423--436},
  year={2008},
  publisher={Cambridge Univ Press}
}

@inproceedings{schrijvers2009complete,
  title={Complete and decidable type inference for GADTs},
  author={Schrijvers, Tom and Peyton Jones, Simon and Sulzmann, Martin and Vytiniotis, Dimitrios},
  booktitle={ACM Sigplan Notices},
  volume={44},
  number={9},
  pages={341--352},
  year={2009},
  organization={ACM}
}

@book{hamming2012,
  title={Numerical methods for scientists and engineers},
  author={Hamming, Richard},
  year={2012},
  publisher={Courier Corporation}
}

@inproceedings{gupta2015,
  title={Deep Learning with Limited Numerical Precision},
  author={Gupta, Suyog and Agrawal, Ankur and Gopalakrishnan, Kailash and Narayanan, Pritish},
  booktitle={Proceedings of the 32nd International Conference on Machine Learning (ICML-15)},
  pages={1737--1746},
  year={2015}
}

@article{eisenberg2015promoting,
  title={Promoting functions to type families in Haskell},
  author={Eisenberg, Richard A and Stolarek, Jan},
  journal={ACM SIGPLAN Notices},
  volume={49},
  number={12},
  pages={95--106},
  year={2015},
  publisher={ACM}
}

@inproceedings{panchekha2015automatically,
  title={Automatically improving accuracy for floating point expressions},
  author={Panchekha, Pavel and Sanchez-Stern, Alex and Wilcox, James R and Tatlock, Zachary},
  booktitle={Proceedings of the 36th ACM SIGPLAN Conference on Programming Language Design and Implementation},
  pages={1--11},
  year={2015},
  organization={ACM}
}
@misc{viewpatterns,
  author = {GHC Wiki},
  title = {View patterns: lightweight views for Haskell},
  url = {https://ghc.haskell.org/trac/ghc/wiki/ViewPatterns},
  note = {Accessed: 2016-06-09}
}

@misc{patternsynonyms,
  author = {GHC Wiki},
  title = {Pattern Synonyms},
  url = {https://ghc.haskell.org/trac/ghc/wiki/PatternSynonyms},
  note = {Accessed: 2016-06-09}
}
\end{filecontents}
\immediate\write18{bibtex paper}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}

\special{papersize=8.5in,11in}
\setlength{\pdfpageheight}{\paperheight}
\setlength{\pdfpagewidth}{\paperwidth}

\conferenceinfo{CONF 'yy}{Month d--d, 20yy, City, ST, Country}
\copyrightyear{20yy}
\copyrightdata{978-1-nnnn-nnnn-n/yy/mm}
\copyrightdoi{nnnnnnn.nnnnnnn}

% Uncomment the publication rights you want to use.
%\publicationrights{transferred}
%\publicationrights{licensed}     % this is the default
%\publicationrights{author-pays}

\titlebanner{Preprint}        % These are ignored unless
\preprintfooter{Preprint}   % 'preprint' option specified.

%\title{What's the point of homoiconicity?}
%\title{The (floating) point of homoiconicity}
%\title{Homoiconicity Without Template Haskell}
\title{Homoicoicity with FAlgebras}
%\subtitle{Functional Pearl}

\authorinfo{Mike Izbicki}
           {UC Riverside}
           {mike@izbicki.me}
%\authorinfo{Name2\and Name3}
           %{Affiliation2/3}
           %{Email2/3}

\maketitle

\begin{abstract}
We say a function is \emph{homoiconic} if it can be converted into an isomorphic abstract syntax tree (AST).
This AST can then be manipulated arbitrarily and converted back into a function.
Template Haskell gives a limited form of homoiconicity to Haskell programs,
but this paper introduces another form.
The technique relies on an isomorphism between certain Haskell classes and FAlgebras.
The \homoiconic library provides tools for using the technique.
%To make the technique more widely applicable,
%we introduce the Haskell community to the heterogeneous FAlgebra
%polymorphism and GHC's type programming capabilities.
%We also present the \homoiconic library that facilitates working with this technique.
%To motivate our technique,
%we construct a small library that automatically transforms numerically unstable code into stable code.

%This paper shows that many Haskell functions are \emph{homoiconic}.
%That is, we can convert these functions into isomorphic abstract syntax trees (ASTs),
%and these ASTs can be converted back into their original Haskell functions.
%%These ASTs are ordinary Haskell data types,
%%so they can be manipulated arbitrarily to perform program transformations.
%The construction does not require template Haskell,
%and so works on expressions available at either compile or run time.
%To motivate this homoiconicity,
%we construct a small library that automatically transforms numerically unstable code into stable code.

%Floating point numbers are dangerous.
%Due to their limited precision,
%seemingly correct mathematical formulae can give wildly inaccurate results.
%This paper shows that Haskell's type system can mitigate this danger.
%
%The main observation is that many numerical Haskell functions are \emph{homoiconic}.
%That is, we can easily convert them into isomorphic abstract syntax trees (ASTs).
%The construction does not use template Haskell, and so works at both compile and run time.
%We will use these ASTs to solve two problems with floating point numbers:
%\begin{enumerate}
%\item
%We will write higher order functions that automatically stabilize (or optimize!) mathematical formulae.
%%This lets one programmer write naive floating point code;
%%then an expert on numerical analysis can write code that automatically improves the naive code.
%\item
%We will specify type class laws for floating point arithmetic that can be automatically tested.
%Existing test frameworks do not work on floating point numbers because floats do not obey many traditional algebraic laws like associativity.
%\end{enumerate}
%We demonstrate these techniques using GHC's built-in numeric class hierarchy,
%but these techniques generalize to user defined class hierarchies as well.
\end{abstract}

%\category{CR-number}{subcategory}{third-level}

% general terms are not compulsory anymore,
% you may leave them out
%\terms
%term1, term2

%\keywords
%floating point, homoiconic, type classes

\section{Introduction}

Template Haskell \cite{sheard2002template} is the standard tool for metaprogramming in Haskell.
%Using quotations, we can convert Haskell code into an abstract syntax tree (AST),
%and using splices, we can insert arbitrary ASTs into our code.
%Template Haskell is enormously useful, but it also has limitations.
In this paper, we introduce a different style of metaprogramming and an accompanying library called \homoiconic.

For example, imagine you're using a library that exports a function
\begin{lstlisting}
logLogistic :: Floating a => a -> a
\end{lstlisting}
There is no way to use Template Haskell to get the abstract syntax tree (AST) of this function.
With \homoiconic, however, we \emph{can} inspect the |logLogistic| function and get its AST.
A ghci session to do this might look like:
\begin{lstlisting}
ghci> logLogistic var1 :: AST Floating Var
(log ((fromInteger 1)/((fromInteger 1)+(exp
    (negate var1)))))
\end{lstlisting}
In this paper, we'll call any function homoiconic if we can convert it into an AST.
So the |logLogistic| function above is homoiconic.

The \homoiconic library also lets us perform arbitrary program transformations.
A careful look at the output above will reveal that |logLogistic| is numerically unstable.
When specialized to the |Double| type,
the |exp| function overflows to infinity for inputs greater than (approximately) $709$.
%This overflow causes |logLogistic| to take the |log| of 0, which is undefined.
Therefore, on an input of $-710$,
|logLogisitic| will take the |log| of 0,
returning negative infinity when the true answer is actually very close to $-710$.
Using \homoiconic, we can write a function
\begin{lstlisting}
stabilize :: AST Floating a -> AST Floating a
\end{lstlisting}
that converts the AST of an unstable function into a stable function.
We could write a similar transformation in Template Haskell,
but there would be no way for us to get the AST to apply it on!

The key idea of the \homoiconic library is simple:
Certain type classes have FAlgebras that completely capture their structure.
From FAlgebras, we can create ASTs.
And we can use these ASTs to represent expressions generated by the corresponding type classes.
%It's important to note that \homoiconic is much more limited than Template Haskell in other ways.
%In particular, it will only work on certain (but not all!) expressions.
%\footnote{
%FAlgebras are a standard Haskell design pattern for domain specific languages.
%There are many existing references, but Data Types \`a la Carte \cite{swierstra2008} is probably the most famous.
%}
%From these FAlgebras, we can in turn generate ASTs for functions.

The remainder of this paper describes these constructions.
Section \ref{sec:homogeneous} introduces \emph{homogeneous} type classes and functions.
Homogeneous type classes have a particularly simple FAlgebra construction that is a natural extension of the Data Types \`a la Carte approach \cite{swierstra2008}.
Section \ref{sec:stabilize} illustrates how to write program transformations like |stabilize| with a handful of examples operating on numerical functions.
Finally, Section 4 introduces \emph{heterogeneous} type classes.
The naming stems from the intuition that homogeneous classes generate ASTs that contain a single type,
but heterogeneous classes generate ASTs that contain multiple types.
The resulting constructions for the heterogeneous case is significantly more complicated.

\section{Homogeneous functions are homoiconic}
\label{sec:homogeneous}

In this section we first define homogeneous type classes and functions.
Then we show that there is an FAlgebra for each homogeneous type class,
and that this FAlgebra makes homogeneous functions homoiconic.
All of the constructions discussed here can be found in \homoiconic's |Homogeneous.FAlgebra| module.

\begin{defn}
We call a type class homogeneous if:
\begin{enumerate}
\item
it has a single parameter of kind |Type|; and
\item
the class's constraints contain only homogeneous type classes applied directly to the parameter.
\end{enumerate}
For example, all of the classes in the Prelude are homogeneous.
Some of these classes are shown in Figure \ref{code:ghc}.
Figure 2 (near the end of the paper) shows type classes which are not homogeneous due to the presence of type families in the constraints.
\end{defn}

\begin{defn}
We call a function homogeneous if:
\begin{enumerate}
\item
there is exactly one type variable in the signature, which we denote by |a|;
\item
each of the function's parameters is either
\begin{enumerate}
\item
|a|, or
\item
concrete;
\end{enumerate}
\item
the function's return type is |a|; and
\item
the constraints contain exactly one homogeneous type classes applied to |a| and nothing else.
\end{enumerate}
The |logLogistic| function is homogeneous,
and Figure \ref{code:ghc} shows many more examples and counterexamples taken from the |Prelude|'s numeric hierarchy.
\end{defn}

%In the remainder of this section we describe a canonical method for constructing FAlgebras from homogeneous type classes and show that this construction makes homogeneous functions homoiconic.
%The construction is tedious to implement by hand,
%so the \homoiconic library provides the function |mkFAlgebra| to automate the boilerplate.
%This function is provided as a convenience and is not strictly necessary for the technique.

%In this section, we will show that every type class has an associated monad representing the abstract syntax tree of the class's homogeneous functions.
%Our construction is closely related to other constructions involving initial algebras, FAlgebras, and free monads.
%See for example \cite{swierstra2008}.

%Our goal in this section is to convert homogeneous functions into ASTs.
%These ASTs will contain only a single parameter type, and so are relatively simple.
%The construction will use FAlgebras\cite{swierstra2008}.

\begin{figure}
\begin{lstlisting}
class Num a where
    (+), (-), (*)       :: a -> a -> a
    negate              :: a -> a
    abs, signum         :: a -> a
    fromInteger         :: Integer -> a

class Num a => Fractional a where
    (/)                 :: a -> a -> a
    recip               :: a -> a
    fromRational        :: Rational -> a

class Fractional a => Floating a where
    pi                  :: a
    exp, log, sqrt      :: a -> a
    (**), logBase       :: a -> a -> a
    sin, cos, tan       :: a -> a
    asin, acos, atan    :: a -> a
    sinh, cosh, tanh    :: a -> a
    asinh, acosh, atanh :: a -> a

class Eq a where
    (==), (/=)          :: a -> a -> Bool

class Eq a => Ord a where
    compare             :: a -> a -> Ordering
    (<),(<=),(>),(>=)   :: a -> a -> Bool
    max, min            :: a -> a -> a
\end{lstlisting}
\caption{
    A portion of the numeric and comparison hierarchies defined in GHC's Prelude.
    %Functions highlighted in bold are homogeneous,
    %and the remainder are not.
}
\label{code:ghc}
\end{figure}

\subsection{A type class for FAlgebras}
Every homogeneous type class has an associated FAlgebra.
We represent this FAlgebra with the following type class.
\begin{lstlisting}
class Functor (Sig alg) => FAlgebra alg where
    data Sig alg a
    runSig :: alg a => Sig alg a -> a
\end{lstlisting}
The |FAlgebra| class is unusual in that its parameter has kind |Type->Constraint|.
This means that instances of |FAlgebra| will be other type classes
(instead of types or type constructors).

It is easiest to understand the |FAlgebra| class by walking through an example instance.
Below is the instance for |Fractional|.
\begin{lstlisting}
instance FAlgebra Fractional where
    data Sig Fractional a
        = Sig_div a a
        | Sig_recip a
        | Sig_fromRational Rational
        | Sig_Fractional_Num (Sig Num a)
    runSig (Sig_div a1 a2)        = a1/a2
    runSig (Sig_recip a)          = recip a
    runSig (Sig_fromRational r)   = fromRational r
    runSig (Sig_Fractional_Num s) = runSig s
\end{lstlisting}

The data family |Sig| encodes what mathematicians call the \emph{signature} of the FAlgebra.
The signature defines all the operations that can be performed on an FAlgebra.
Each |Sig| data instance can have many constructors,
and these constructors come in two flavors.
First is the \emph{function constructor}.
There should be one function constructor for each homogeneous class function, and
this constructor should have the same parameters as the function.
For the |Fractional| example, we've defined the three constructors |Sig_div|, |Sig_recip|, and |Sig_fromRational| for the three class methods |(/)|, |recip|, and |fromRational| respectively.
The second constructor flavor is the \emph{superclass constructor}.
There should be one superclass constructor for each superclass, and
this constructor should store the |Sig| of the corresponding superclass.
For the |Fractional| example, we have the |Sig_Fractional_Num| constructor corresponding to the |Num| superclass.

The |runSig| class method evaluates an FAlgebra's signature.
Mathematicians sometimes call this function simply an \emph{algebra}.
For each function constructor, |runSig| should call the corresponding function.
For each superclass constructor, |runSig| recursively calls |runSig| on the superclass's |Sig|.
This is exactly what the |Fractional| instance above does.

The F in FAlgebra comes from the fact that every signature is actually a functor.
In Haskell, we encode this by enforcing that |Sig alg| must be an instance of the |Functor| class.
As usual, there is only a single valid |Functor| instance.
For |Fractional|, it is:
\begin{lstlisting}
instance Functor (Sig Fractional) where
    fmap f (Sig_div a1 a2) = Sig_div (f a1) (f a2)
    fmap f (Sig_recip a) = Sig_recip (f a)
    fmap f (Sig_fromRational r) = Sig_fromRational r
    fmap f (Sig_Fractional_Num s) = fmap f s
\end{lstlisting}

\subsection{Constructing the AST}
\label{sec:hom.cons}

For every FAlgebra, there is an associated AST.
This AST is sometimes called an \emph{initial algebra},
and has a standard construction via the \emph{free monad}.
In Haskell, the free monad is defined as
\begin{lstlisting}
data Free f a
    = Pure a
    | Free (f (Free f a))
\end{lstlisting}
which lets us define our AST as
\begin{lstlisting}
type AST alg a = Free (Sig alg) a
\end{lstlisting}
Intuitively,
the |Pure| constructor represents a leaf in the AST,
and the |Free| constructor represents a branch.
The parameter to |Free| is filled by the appropriate |Sig| data instance.
The constructor used for the |Sig| instance corresponds to an operation,
and the parameters to the constructor will contain ASTs nested recursively.

For example, consider the expression |(1+2)+3|.
We can create a corresponding AST using |Num|'s |FAlgebra| instance.
\begin{lstlisting}
expr1 :: AST Num Double
expr1 = Free
  (Sig_plus
    (Free
      (Sig_plus
        (Pure 1)
        (Pure 2)
      )
    )
    (Pure 3)
  )
\end{lstlisting}
The type signature is not necessary, but shown for clarity.

We can also create an AST for the same expression using any subclass of |Num|.
Below is the same expression encoded using |Floating|'s |FAlgebra| instance.
\begin{lstlisting}
expr2 :: AST Floating Double
expr2 = Free
  (Sig_Floating_Fractional
    (Sig_Fractional_Num
      (Sig_plus
        (Free
          (Sig_Floating_Fractional
            (Sig_Fractional_Num
              (Sig_plus
                (Pure 1)
                (Pure 2)
              )
            )
          )
        )
        (Pure 3)
      )
    )
  )
\end{lstlisting}
Notice that the |Sig_plus| constructor must be embedded into |Floating|'s |Sig| with calls to |Sig_Floating_Fractional| and |Sig_Fractional_Num|.
These embeddings create considerable boilerplate,
making the construction of ASTs by hand a tedious process.

We can avoid this boilerplate with a type class that performs these embeddings for us.\footnote{
    The name {\ttfamily View} stems from the fact that the class methods are actually what GHC calls ``view patterns.''
    See Section \ref{sec:viewpatterns} for details on how the {\ttfamily ViewPatterns} language extension lets us use the {\ttfamily View} type class for easier pattern matching on our ASTs.
}
\begin{lstlisting}
class (FAlgebra alg1, FAlgebra alg2)
    => View alg1 alg2 where
    embedSig         :: Sig alg1 a -> Sig alg2 a
    unsafeExtractSig :: Sig alg2 a -> Sig alg1 a
\end{lstlisting}
Instances of |View| should satisfy the property that |alg1| is either equal to |alg2| or is a superclass of |alg2|, and
all such relationships should have a corresponding instance.
This property ensures that the |Sig alg1 a| data instance can always be embedded into a |Sig alg2 a| data instance (via a chain of superclass constructors).
It is only sometimes true that we can extract a |Sig alg1 a| from a |Sig alg2 a|,
so the function is partial and hence labeled |unsafe|.
For example,
we have the following |View Num Floating| instance because |Num| is a superclass of |Floating| via |Fractional|.
\begin{lstlisting}
instance View Num Floating
    embedSig s
        = Sig_Fractional_Floating (embedSig s)
    unsafeExtractSig (Sig_Fractional_Floating s)
        = unsafeExtractSig s
\end{lstlisting}
The |embedSig| function shows us how to embed a |Sig Num| into a |Sig Floating| by calling the appropriate superclass constructors.
Notice that the recursive call to |embedSig| relies on a |View Num Fractional| instance also existing.
Similarly, the |unsafeExtractSig| function extracts the |Sig Num| instance by pattern matching on the appropriate superclass constructors.

Armed with this |View| class, we can create a uniform representation for |FAlgebra|'s ASTs.
The expression |(1+2)+3| can now be represented polymorphically as:
\begin{lstlisting}
expr3 :: View Floating alg => AST alg Double
expr3 = Free
  (embedSig
    (Sig_plus
      (Free
        (embedSig
          (Sig_plus
            (Pure 1)
            (Pure 2)
          )
        )
      )
      (Pure 3)
    )
  )
\end{lstlisting}

Using our uniform representation of an AST,
we can make the |AST| type an instance of any homogeneous type class.
As an example, the |Fractional| instance is shown below.
\begin{lstlisting}
instance
    ( View Fractional alg
    , View Num alg
    ) => Fractional (AST alg a) where
    (/) e1 e2 = Free $ embedSig $ Sig_div e1 e2
    recip e   = Free $ embedSig $ Sig_recip e
    fromRational r
        = Free $ embedSig $ Sig_fromRational r
\end{lstlisting}
For each function in the type class,
we simply embed the function's constructor into the AST by prepending the expression |Free $ embedSig $|.
The constrainst |View num alg| is not used directly in the instance.
It is inherrited from the |Num (AST alg a)| instance,
where it is used directly.
In general, a type class instance for |AST| will require a |View| constraint for every superclass,
not just those parent classes listed in the context.

These instances let us easily create ASTs.
The |Num| AST can be created with the expression
\begin{lstlisting}
expr4 :: AST Num Double
expr4 = (1+2)+3
\end{lstlisting}
And the |Floating| AST can be created by just changing the type signature.
\begin{lstlisting}
expr5 :: AST Floating Double
expr5 = (1+2)+3
\end{lstlisting}
Notice that in these last two examples we did not embed the numbers into the AST with the |Pure| constructor.
Since |AST| is an instance of |Num|,
GHC will call |fromInteger| to embed the number for us automatically.

\subsection{Showing the AST}
Now that we can create our ASTs, we want to actually do something with them!
In this section we will convert them into a |String| for display.
This is an easy procedure of writing |Show| instances for the |Sig| and |Free| data types.

There are no tricks in the |Show| instance for |Sig|.
The instance for |Fractional| is shown below.
\begin{lstlisting}
instance Show a => Show (Sig Fractional a) where
    show (Sig_div a1 a2) = show a1++"/"++show a2
    show (Sig_recip a) = "recip "++show a
    show (Sig_fromRational r) = "fromRational "++show r
    show (Sig_Fractional_Num s) = show s
\end{lstlisting}
For each function constructor, we simply show the corresponding function and its parameters.
If the function is an operator, we'll display it infix for convenience.
For each superclass constructor, we simply recursively call show on the superclass's |Sig|.

The |Free| type's |Show| instance is similarly straightforward.
\begin{lstlisting}
instance (Show a, Show (f (Free f a)))
    => Show (Free f a) where
    show (Pure a) = show a
    show (Free f) = "("++show f++")"
\end{lstlisting}
If the syntax tree contains only a single leaf, we just show that leaf.
If the syntax tree contains a branch,
then put parenthesis around the branch,
and show the functor (i.e. the |Sig|) in the middle.

Now, when we type a numeric expression into ghci without a type signature,
ghci will evaluate the expression like normal.
\begin{lstlisting}
ghci> (1+2)+3
6
\end{lstlisting}
But when we add the appropriate type signature,
the full AST is displayed.
\begin{lstlisting}
ghci> (1+2)+3 :: AST Floating Double
(((fromInteger 1)+(fromInteger 2))+(fromInteger 3))
\end{lstlisting}
Again, the way ghci works, all integer literals automatically have |fromInteger| applied to them,
which is why this function appears in the AST above.
It would be easy to create a pretty printer that does not display |fromInteger| or the excess parentheses,
%but this is left as an exercise for the reader :)
but we that would take us too far afield here.

\subsection{Showing functions}
Reconsider our |logLogistic| function.
It has type
\begin{lstlisting}
logLogistic :: Floating a => a -> a
\end{lstlisting}
What happens if we specialize the |a| parameter to be an |AST|?
We'll get a peek at the function's internals.
\begin{lstlisting}
ghci> logLogistic 1 :: AST Floating Double
(log ((fromInteger 1)/((fromInteger 1)+(exp
    (negate (fromInteger 1))))))
\end{lstlisting}
We don't just have to input single numbers;
we can also input full expressions.
These expressions will also get displayed,
intermixed with the original function.
\begin{lstlisting}
ghci> logLogistic (1*3+4) :: AST Floating Double
(log ((fromInteger 1)/((fromInteger 1)+(exp
    (negate (((fromInteger 1)*(fromInteger 3))
    +(fromInteger 4)))))))
\end{lstlisting}
And we can even display the resulting AST of nested function calls.
\begin{lstlisting}
ghci> logLogistic (logLogistic 1)
    :: AST Floating Double
(log ((fromInteger 1)/((fromInteger 1)+(exp
    (negate (log ((fromInteger 1)/((fromInteger 1)
    +(exp (negate (fromInteger 1)))))))))))
\end{lstlisting}
It would be nice if the displayed function could show variables,
rather than just numbers.
To accomplish this, we need a variable type.
\begin{lstlisting}
newtype Var = Var String
\end{lstlisting}
Values of type |Var| cannot be plugged directly into the |logLogistic| function because |Var| is not an instance of |Floating|.
Fortunately, we have a way to make any type an instance of |Floating| via |Floating|'s |AST| type.
More generically, we define the following variables.
\begin{lstlisting}
var1 :: AST alg Var
var1 = Pure "var1"

var2 :: AST alg Var
var2 = Pure "var2"

var3 :: AST alg Var
var3 = Pure "var3"
\end{lstlisting}
And we can use them to recover the exact AST of a function.
\begin{lstlisting}
ghci> logLogistic var1 :: AST Floating Var
(log ((fromInteger 1)/((fromInteger 1)+(exp
    (negate var1)))))
\end{lstlisting}
At this point, you might be tempted to write a |Show| instance for functions.
\begin{lstlisting}
instance
    ( FAlgebra alg
    , Show (Sig alg (Free (Sig alg) Var))
    ) => Show (AST alg Var -> AST alg Var) where
    show f = show (f var1)
\end{lstlisting}
Unfortunately, if you try to use the instance naively
\begin{lstlisting}
ghci> logLogistic
\end{lstlisting}
then ghci will complain about ambiguous type variables.
GHC's defaulting mechanism is not powerful enough for it to properly specialize the function without a type signature.
So while this construction does give us a convenient way to inspect the contents of a function,
it's not quite powerful enough for a proper |Show| instance.

\subsection{Evaluating the syntax tree}
Our last task is to evaluate the ASTs.
That is, we need to run them to generate the value the tree represents.

To do this, we will take advantage of the free monad's structure.
(Recall that the |AST| type we've been using is a synonym for the free monad.)
The free monad is so called because as long as the parameter |f| is a |Functor|,
then |Free| has a valid |Monad| instance.
Since all |Monad|s are by necessity also |Functor|s,
|Free| has a valid |Functor| instance as well.
\begin{lstlisting}
instance Functor f => Functor (Free f) where
    fmap g (Pure a) = Pure (g a)
    fmap g (Free f) = Free (fmap (fmap g) f)
\end{lstlisting}
For our purposes, that's all the structure we'll need.

The following simple function evaluates the syntax tree.
\begin{lstlisting}
runAST :: (FAlgebra alg, alg a) => AST alg a -> a
runAST (Pure a) = a
runAST (Free f) = runSig (fmap evalHom f)
\end{lstlisting}
If our syntax tree already consists of just a single value (i.e. it is the |Pure| constructor),
then we just return that value.
Otherwise, we use the |Functor| instance to recursively convert the |Sig|s into types of |a|,
combining the results with |runSig|.

When we evaluate an AST for an expression,
we get the same result as if we had just evaluated the expression directly.
\begin{lstlisting}
ghci> logLogistic 10 :: Double
-4.539889921682063e-5

ghci> runAST (logLogistic 10 :: AST Floating Double)
-4.539889921682063e-5
\end{lstlisting}
We've finally demonstrated that homogeneous functions are in fact homoiconic.

\subsection{Boilerplate}

For each homogeneous type class,
there are many boilerplate instances that we need to write.
The \homoiconic library provides a template Haskell function |mkFAlgebra| in the |Homogeneous.FAlgebra| module that generates the |FAlgebra|, |Functor|, |Show|, and |View| instances plus all of the pattern synonyms (discussed in the next section) for a given class.
All of constructions above can be generated by the single invocation
\begin{lstlisting}
mkFAlgebra ''Fractional
\end{lstlisting}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Writing program transformations}
\label{sec:stabilize}

We're now ready to write program transformations that manipulate the ASTs created in the previous section.
In this section, we'll first demonstrate how to pattern match on our ASTs using the |ViewPatterns| and |PatternSynonyms| language extensions.
%Then we'll see three simple examples of program transformations implemented in this way.
We'll also see three motivating examples of useful transformations on floating point operations.

%Automatically stabilizing floating point expressions is an active area of research.
%One way of doing this is to create a library of program transformations that fix many different types of expressions.
%Then combining everything in the library on your problem.
%In this section, we'll create a very small library for these floating point issues,
%and don't claim to have completely solved the floating point problem.
%This is simply a motivating example for homoiconicity.

\subsection{Pattern matching the AST}
\label{sec:patternmatch}

Consider the following simple,
but numerically unstable function.
\begin{lstlisting}
testFunc1 :: Floating a => a -> a
testFunc1 = log (exp a)
\end{lstlisting}
As in our |logLogistic| function,
|testFunc| gives incorrect answers when |a| is specialized to |Double|.
Inputs greater than (approximately) 710 cause the |exp| function to overflow to infinity;
the log of infinity is still infinity;
so the returned answer is infinity.
But this wrong.
On the real numbers, the $\log$ function is defined to be the inverse of $\exp$,
so the final result should be exactly the same as the input.
We'll write a program transformation that stabilizes the |testFunc1| function,
then we'll demonstrate how the |ViewPatterns| and |PatternSynonyms| language extensions simplify this transformation.
\label{sec:viewpatterns}

Our goal is to take an input AST,
find all occurrences of the expression |log (exp x)|,
and replace them with just |x|.
(Here |x| can be an arbitrary AST, not just a single value.)
We will create a series of four functions to accomplish this task,
each improving on the previous.
Here is the first.
\begin{lstlisting}
logexpAST1 :: AST Floating a -> AST Floating a
logexpAST1 (Free (Sig_log (Free (Sig_exp a)))) = a
\end{lstlisting}
This function has two syntactic warts.
First, the pattern is verbose.
To properly match the expression, we must alternate between the |Free| and |Sig_| constructors.
It would be better to have a single constructor per operation.
Second, the function is specialized to the |Floating| type class.
We would like our transformation to also works on subclasses of |Floating|.

We'll start by correcting the second problem.
The |ViewPatterns| language extension provides syntactic sugar that lets us pattern match on the return value of a function.\footnote{
    The GHC wiki \cite{viewpatterns} provides details on exactly how the desugaring works.
}
We can use |ViewPatterns| to write polymorphic patterns by using polymorphic functions in the pattern.
We need a polymorphic function for extracting a |Sig alg a| type from a |Sig Floating a| whenever |alg| is a subclass of |Floating|.
Fortunately, we've already defined such a function:
\begin{lstlisting}
unsafeExtractSig :: View alg1 alg2
    => Sig alg2 a -> Sig alg1 a
\end{lstlisting}
Using it in the pattern gives us our second program transformation.
\begin{lstlisting}
logexpAST2 :: View Floating alg
    => AST alg a -> AST alg a
logexpAST2
    (Free (unsafeExtractSig -> Sig_log
    (Free (unsafeExtractSig -> Sig_exp a))))
    = a
\end{lstlisting}
This modified transformation has the correct polymorphic type signature
(so we've solved problem 2),
but the pattern matches are even uglier
(so we've made problem 1 worse).

The |PatternSynonyms| extension lets us define new patterns,\footnote{
    Again, see the GHC Wiki \cite{patternsynonyms} for details on this language extension.
}
and we will use this feature to clean up our syntax.
Specifically, we define a pattern synonym for each function contained in an FAlgebra.
Our naming convention is to prefix |AST_| to the name of the function.
These pattern synonyms combine the |Free| constructor with the view pattern from the previous example.
The synonyms for the |log| and |exp| functions are shown below.
\begin{lstlisting}
pattern AST_log :: View Floating alg
    => AST alg a -> AST alg a
pattern AST_log e
    <- Free (unsafeExtractSig -> Sig_log e)

pattern AST_exp :: View Floating alg
    => AST alg a -> AST alg a
pattern AST_exp e
    <- Free (unsafeExtractSig -> Sig_exp e)
\end{lstlisting}
Armed with these pattern synonyms,
we can rewrite our function in a much simpler form.
\begin{lstlisting}
logexpAST3 :: View Floating alg
    => AST alg a -> AST alg a
logexpAST3 (AST_log (AST_exp a)) = a
\end{lstlisting}
This simple function works on our the motivating test case:
\begin{lstlisting}
ghci> logexpAST3 $ testFunc1 var1 :: AST Floating Var
var1
\end{lstlisting}
%stopzone
but it fails on this slightly more complex function:
\begin{lstlisting}
testFunc2 :: Floating a => a -> a
testFunc2 a = 1+exp(log a)
\end{lstlisting}
The problem is that we haven't told our program transformations what to do when they don't pattern match!
When pattern matching fails, we want our transformations to recurse into the subexpressions,
applying the transformations there as well.
In the free monad, recursion is handled by a call to |fmap| and the base case is handled by extracting the contents of |Pure|.

Here is our final version of the program transformation.
\begin{lstlisting}
logexpAST4 :: View Floating alg
    => AST alg a -> AST alg a
logexpAST4 (AST_log (AST_exp a)) = a
logexpAST4 (Free f) = Free (fmap logexpAST4 f)
logexpAST4 (Pure a) = Pure a
\end{lstlisting}
It correctly recurses into subexpressions.
\begin{lstlisting}
ghci> logexpAST4 $ testFunc2 var1
    :: AST Floating Var
((fromInteger 1)+var1)
\end{lstlisting}
%stopzone
But there's still one last wrinkle.
What if we need to apply the program transformation multiple times?
Consider the following test function.
\begin{lstlisting}
testFunc3 :: Floating a => a -> a
testFunc3 a = 1+log(log(log(exp(exp(exp a)))))
\end{lstlisting}
Applying our program transformation directly doesn't correct the function because the transformation needs to be applied repeatedly.
\begin{lstlisting}
ghci> logexpAST4 $ testFunc3 var1
    :: AST Floating Var
((fromInteger 1)+(log (log (exp (exp var1)))))
\end{lstlisting}
%stopzone
What we want is the \emph{fixed point} of the program transformation.
That is, we want to apply the program transformation repeatedly until it stops changing the AST.
The |fixAST| function below takes as input a transformation and returns the fixed point of that transformation.
\begin{lstlisting}
fixAST ::
    ( Eq (Sig alg (Free (Sig alg) a))
    , Eq a
    ) => (AST alg a -> AST alg a)
      -> (AST alg a -> AST alg a)
fixAST f ast = if ast==ast'
    then ast
    else fixAST f ast'
    where
        ast' = f ast
\end{lstlisting}
Now we can correctly modify the |testFunc3| function.
\begin{lstlisting}
ghci> fixAST logexpAST4 $ testFunc3 var1
    :: AST Floating Var
((fromInteger 1)+var1)
\end{lstlisting}
%stopzone
And that's all there is to writing a program transformation.
More complex transformations just involve more complex pattern matching.

\subsection{More complex transformations}

The transformation in in the previous section is relatively simple.
For example, it could have been implemented using GHC's rewrite rules \cite{jones2001playing}.
Rewrite rules are the primary mechanism for optimising source code in GHC,
but they are limited to transformations that involve no computation.
This limitation prevents rewrite rules from implementing a number of optimizations,
one of them being being constant folding.
Constant folding is the process of reducing an expression containing several constants into a single constant.
For example, converting the expression |(1+2)+3| into just the number |6|.
%(Due to this limitation, GHC has special ad-hoc code just for constant folding.)
Our program transformations can implement arbitrary computation and so are powerful enough to handle constant folding.

The following function performs constant folding on expressions containing addition and multiplication of integers.
\begin{lstlisting}
foldConstants :: View Num alg
    => AST alg a -> AST alg a
foldConstants (AST_plus
    (AST_fromInteger a1)
    (AST_fromInteger a2))
    = AST_fromInteger (a1+a2)
foldConstants (AST_mul
    (AST_fromInteger a1)
    (AST_fromInteger a2))
    = AST_fromInteger (a1*a2)
foldConstants (Free sig)
    = Free (fmap foldConstants sig)
foldConstants (Pure a) = Pure a
\end{lstlisting}
It is straightforward to extend this function to work for other operations,
but for space reasons these were omitted.

Let's see an example of constant folding in action.
First define a simple function with two parameters and a handful of constants.
\begin{lstlisting}
func :: Num a => a -> a -> a
func x1 x2 = x1*2+(7+2)*x2
\end{lstlisting}
If we call |func| with two constant parameters,
our |foldConstants| function is able to simplify the resulting expression into a single constant.
\begin{lstlisting}
ghci> fixAST foldConstants (func 2 3)
    :: AST Floating Double
(fromInteger 31)
\end{lstlisting}
Alternatively, we can call the function with two variable parameters.
Only the constants in the original function will be folded.
\begin{lstlisting}
ghci> fixAST foldConstants (func var1 var2)
    :: AST Floating Var
((var1*(fromInteger 2))+((fromInteger 9)*var2))
\end{lstlisting}
And finally, we can call the function with one constant and one variable parameter.
\begin{lstlisting}
ghci> fixAST foldConstants (func var1 3)
    :: AST Floating Var
((var1*(fromInteger 2))+(fromInteger 27))
\end{lstlisting}

\subsection{The log-logistic function}

Now let's see how to stabilize the |logLogistic| function.
Here's an example of what a stable implementation might look like.
\begin{lstlisting}
logLogistic2 :: (Floating x, Ord x) => x -> x
logLogistic2 x = m+log(1/(exp(m)+exp(-x+m)))
    where
        m = min 0 x
\end{lstlisting}
Notice that it has a different type signature---we've had to add the |Ord| constraint due to the use of the |min| function.
Recall that one of the requirements for a function to be homogeneous is that it have only a single class in the context.
Therefore the stabilized function |logLogistic2| is not homogeneous.

We can make an equivalent implementation, however, that is homogeneous by introducing the following type class
\begin{lstlisting}
class (Floating a, Ord a) => FloatingOrd a
\end{lstlisting}
and the following instance
\begin{lstlisting}
instance {-#OVERLAPPABLE#-} (Floating a, Ord a)
    => FloatingOrd a
\end{lstlisting}
Note that the |OVERLAPPABLE| pragma is required so that we can create an |Ord| instance for |AST FloatingOrd a| per the construction in Section \ref{sec:hom.cons}.

We can now write a function that stabilizes |logLogistic|
\begin{lstlisting}
stabilize :: AST Floating a -> AST FloatingOrd a
stabilize
    (AST_log
        (AST_div
            (AST_fromInteger 1)
            (AST_plus
                (AST_fromInteger 1)
                (AST_exp
                    (AST_negate x)
                )
            )
        )
    )
    = m+log(1/(exp(m)+exp(-x+m)))
        where
            m = min 0 x
\end{lstlisting}
Notice that in this transformation, the type signature of the AST actually changes.

This transformation works, but it feels like cheating.
If we have to manually write a unique program transformation for every numeric function,
then we're not reducing our workload.
Fortunately we don't have to.
Designing generic program transformations that stabilize floating point numbers is an actively researched problem.
For example, a team from the University of Washington recently created the Herbie tool to stabilize floating point expressions \cite{panchekha2015automatically}.
The output of such a program can easily be used to implement a significantly more advanced version of |stabilize|.
%Since we can perform arbitrary computations inside our program transformations,
%there's nothing stopping us from just plugging
%Actually doing this is left as an exercise for the reader.
%Any of these techniques can be used with these program transformations described in this section.
%We can use programs like herbie within our Haskell programs.
%In order to call out to a foreign program, we need to be in the |IO| monad.
%\begin{lstlisting}
%herbie :: AST Floating a -> IO (AST FloatingOrd a)
%\end{lstlisting}
%The is essentially how the Herbie GHC plugin works.

\section{Heterogeneous functions are homoiconic}

In the 1970's, mathematicians noticed a deficiency in the definition of FAlgebras.
The signature of an FAlgebra can only contain a single type,
but many structures involve multiple types.
For example, the definition of a vector space requires both a scalar type and a vector type.
The concept of heterogeneous FAlgebras was introduced to formalize these algebraic structures over multiple types \cite{birkhoff1970heterogeneous}.

%The same pattern happens in Haskell.
Similarly in Haskell, homogeneous type classes are not sufficient to describe all the structures we want to work with.
For example, Figure \ref{code:vector} shows a simple extension to GHC's numerics hierarchy for working with vectors.
The |Vector| and |Hilbert| type classes are not homogeneous because they rely on a type family to describe the relationship between multiple types.
Using this class hierarchy, we can implement functions like the logistic loss:
\begin{lstlisting}
logLoss :: Vector a => a -> a -> Scalar a
logLoss a1 a2 = logLogistic (dotproduct a1 a2)
\end{lstlisting}
And again, this function is not homogeneous due to the type family in the signature.
Nonetheless, we would still like to be able to convert this function into an AST as we did for homogeneous functions.

In this section we introduce the notion of heterogeneous type classes and functions.
We will see that for every heterogeneous type class,
there exists a corresponding heterogeneous FAlgebra.
From this heterogeneous FAlgebra,
we can construct an AST using the heterogeneous free monad.
This construction gives us homoiconicity for heterogeneous functions.
Unfortunately, type families as implemented in GHC Haskell have many limitations,
and the limitations will complicate the heterogeneous constructions.
We will require considerably more type hackery in this section.
Fortunately, this complexity is contained within the construction of the heterogeneous AST.
From a user's perspective, the heterogeneous AST is just as easy to work with as the homogeneous one.

\begin{figure}
\begin{lstlisting}
type family Scalar a

class (Num a, Floating (Scalar a))
    => Vector a where
    (.*) :: Scalar a -> a -> a

class Vector a => Hilbert a where
    dotproduct :: a -> a -> Scalar a

data Vec3 = Vec3 a a a
type Scalar (Vec3 a) = a
\end{lstlisting}
\caption{
    A simple extension to GHC's numeric hierarchy for vector arithmetic.
    A vector space is a special type of number---{\ttfamily (+)} represents vector addition, and {\ttfamily (*)} represents elementwise multiplication---that has an associated {\ttfamily Scalar} type and the ability to perform scalar multiplication with {\ttfamily (.*)}.
    A Hilbert space is a vector space with dot products.
}
\label{code:vector}
\end{figure}

%Unfortunately, this function is not homogeneous due to the application of a type family in the return type.
%So we cannot use the construction of Section \ref{sec:homogeneous} to generate an AST for this function.
%In this section, we introduce the more general notion of heterogeneous type classes and functions.
%These concepts are called heterogeneous because they allow the construction of ASTs over multiple types through the use of type families.

\begin{defn}
We call a type class heterogeneous if:
\begin{enumerate}
\item
it has a single parameter of kind |Type|; and
\item
the class's constraints contain only heterogeneous type classes applied either directly to the parameter \emph{or to a type family applied to a parameter}.
\end{enumerate}
For example, every homogeneous type class is also heterogeneous.
The type classes in Figure 2 are all heterogeneous, but not homogeneous.
%Multiparameter type classes are not heterogeneous.
\end{defn}

\begin{defn}
We call a function heterogeneous if:
\begin{enumerate}
\item
there is exactly one type variable in the signature, which we denote by |a|;
\item
each of the function's parameters is either
\begin{enumerate}
\item
|a|,
\item
concrete, or
\emph{
\item
a type family applied to }|a|;
\end{enumerate}
\item
the function's return type is either |a| \emph{or a type family applied to} |a|; and
\item
the constraints contain only heterogeneous type classes applied to |a| \emph{or type family applied to} |a|.
\end{enumerate}
All homogeneous functions are heterogeneous.
The |logLoss| function is heterogeneous but not homogeneous.

Heterogeneous functions come in two types.
Type 0 functions have no type family applications in the return type.
For example, |(.*)| is a type 0 function.
Type 1 functions have one type family application in the return type.
For example, |dotProduct| is a type 1 function.\footnote{
In general, a type $n$ function has $n$ type family applications in the return type.
The techniques in this section can be used to support type $n$ functions for arbitrary $n$,
but for simplicity, we restrict ourselves to just type 0 and 1 functions.
}
\end{defn}

\begin{note}
The heterogeneous constructions in this section will use many of the same names as the homogeneous constructions in Section \ref{sec:homogeneous}.
Unless its clear from context, we will always be referring to the heterogeneous version of the construction for the remainder of the paper.
In the \homoiconic library, the constructions in this section are contained in the |Heterogeneous.FAlgebra| module.
\end{note}

\subsection{The problems of heterogeneous types}
\label{sec:het.probs}
Before describing how to construct the heterogeneous ASTs,
we will look at three problems that type families introduce to the homogeneous AST construction.

\begin{problem}[the superclass problem]
Consider the |Vector| class in Figure \ref{code:vector}.
This class is not homogeneous because of the superclass constraint involving a type family application.
If we follow the formulation for making a homogeneous FAlgebra, we get
\begin{lstlisting}
instance FAlgebra Vector where
    data Sig Vector a
        = Sig_dotmul (Scalar a) a
        | Sig_Vector_Num (Sig Num a)
        | Sig_Vector_Floating
            (Sig Floating (Scalar a))
    runSig (Sig_dotmul s a) = s.* a
    runSig (Sig_Vector_Num s) = runSig s
    runSig (Sig_Vector_Floating s) = runSig s
\end{lstlisting}
This definition does not type check.
In the last clause of |runSig|'s definition,
the type checker will try to match the |a| type with |Scalar a| (because |s| has type |Sig Floating (Scalar a)| instead of |Sig Floating a|) and fail.
To fix this problem, we will need to modify the way we create superclass constructors.
\end{problem}

\begin{problem}[the parameter problem]
Now consider what happens when we write the |Functor| instance
\begin{lstlisting}
instance Functor (Sig Vector) where
    fmap f (Sig_dotmul s a) = Sig_dotmul (f s) (f a)
    fmap f (Sig_Vector_Num s) = Sig_Vector_Num (f s)
    fmap f (Sig_Vector_Floating s)
        = Sig_Vector_Floating (f s)
\end{lstlisting}
Here type checking fails on |fmap|'s first clause in the expression |(f s)|.
The function |f| has type |a->b|, but the |s| variable has type |Scalar a|.
To fix this problem, we will need a modified |fmap| function.
\end{problem}

\begin{problem}[the return type problem]
Consider the |Hilbert| class in Figure \ref{code:vector}.
The |dotProduct| function is not homogeneous because of the type family in the return type.
If we follow the formulation for making a homogeneous FAlgebra, we get
\begin{lstlisting}
instance FAlgebra Hilbert where
    data Sig Hilbert a
        = Sig_Hilbert_Module (Sig Module a)
        | Sig_dotProduct a a
    runSig (Sig_Hilbert_Module s) = runSig s
    runSig (Sig_dotProduct a1 a2) = dotProduct a1 a2
\end{lstlisting}
Here, type checking fails in the last clause of |runSig|.
The return type of |runSig| should be |a|,
but |dotProduct| returns a |Scalar a|.
To fix this problem, we need to change the way we run a signature.
\end{problem}

\subsection{Dealing with type families}
To address these problems, we first need to consider a limitation of GHC's type families.
Consider the declaration
\begin{lstlisting}
newtype Wrap1 (t::Type->Type) a = Wrap1 (t a)
\end{lstlisting}
The list constructor |[]| has kind |Type->Type|,
so the following expression type checks.
\begin{lstlisting}
Wrap1 [1] :: Wrap1 [] Int
\end{lstlisting}
The |Scalar| type family also has kind |Type->Type|,
so we would like to use it similarly.
\begin{lstlisting}
Wrap1 1 :: Wrap1 Scalar (Vec3 Int)
\end{lstlisting}
Unfortunately, this expression does not type check because GHC requires that type families be fully applied anywhere they appear in a type signature.
In this section, we will create a workaround that allows us to pass type families as arguments to types.\footnote{
    The {\ttfamily singletons} package provides a similar construction in Section 4.3 of the packages paper \cite{eisenberg2015promoting}.
    %The {\ttfamily singletons}' construction is more general than the one presented here.
    Their construction allows for the promotion of ordinary functions to type families,
    and is therefore more complicated.
    For ease of presentation, we do not use their construction.
}

The first step is to create a new data type for each type family.
The naming convention used by \homoiconic is to put a |T| in front of the family's name.
For example, we declare
\begin{lstlisting}
data TScalar
\end{lstlisting}
for the type family |Scalar|.
We call types created in this way ``tags,''
and create the following type synonym to refer to them.
\begin{lstlisting}
type Tag = Type
\end{lstlisting}
We would get more type safety if |Tag| were introduced as a new kind distinct from |Type|;
but this requires open kinds, which is a feature not yet available in GHC.\footnote{
    Issue \#11080 on GHC Trac has an extensive discussion of this feature.
    See \url{https://ghc.haskell.org/trac/ghc/ticket/11080}.
}

Next, we need a way to apply tags to a type as if they were a type family.
The |AppTag| type family serves this role.
\begin{lstlisting}
type family AppTag (t::Tag) (a::Type) :: Type
\end{lstlisting}
The |t| parameter is the tag representing the type family we want to apply,
and the |a| parameter is the type to which we want to apply the family.
The |Scalar| instance looks like
\begin{lstlisting}
type instance AppTag TScalar a = Scalar a
\end{lstlisting}
And now we can create a modified version of our |Wrap1| type above that works for type families.
\begin{lstlisting}
newtype Wrap2 (t::Tag) a = Wrap2 (AppTag t a)
\end{lstlisting}

Frequently, we will want to deal with not just a single type family application,
but rather a sequence of zero or more type family applications.
We can represent these applications with kind |[Tag]| using GHC's type level lists.
The following type family applies a sequence of tags to a type.
\begin{lstlisting}
type family AppTags (t::[Tag]) (a::Type) :: Type
type instance AppTags '[]       a = a
type instance AppTags (x ': xs) a
    = AppTag x (AppTags xs a)
\end{lstlisting}
For example, the type
|AppTags '[TScalar,TScalar] a|
is equivalent to the type
|Scalar (Scalar a)|,
and
|AppTags '[] a| is equivalent to |a|.
%\begin{lstlisting}
%AppTags '[TScalar,TScalar] a
%\end{lstlisting}
%is equivalent to the type
%\begin{lstlisting}
%Scalar (Scalar a)
%\end{lstlisting}

Now we can create an even more powerful wrapper that can handle arbitrary applications of type families.
\begin{lstlisting}
newtype Wrap3 (t::[Tag]) a = Wrap3 (AppTags t a)
\end{lstlisting}

\subsection{Heterogeneous FAlgebras}

At last we are ready to see our type class for heterogeneous FAlgebras.
\newpage
\begin{lstlisting}
class FAlgebra alg where
  data Sig alg (t::[Tag]) a

  runSig0 :: alg a => proxy a
    -> Sig alg t (AppTags t a)
    -> AppTags t a

  runSig1 :: alg a => proxy a
    -> Sig alg (s ': t) (AppTags t a)
    -> AppTags (s ': t) a

  mapRun
    :: (forall s. Free (Sig alg') s a -> AppTags s a)
    -> Sig alg t (Free (Sig alg') t' a)
    -> Sig alg t (AppTags t' a)
\end{lstlisting}
Don't panic!
Understanding exactly how this class works is not necessary for using the ASTs it generates.
(To just get a feel for using the heterogeneous ASTs,
skim the rest of this paper for code snippets containing \textbf{\footnotesize\ttfamily ghci}.)

%We now begin the step-by-step explanation of the heterogeneous |FAlgebra|.
%The most important difference between the homogeneous and heterogeneous |FAlgebra| class is that the |Sig| data family has been given a new type parameter |t::[Tag]|.
%This parameter tells us which type families have been applied to the variable |a|.
%Exactly what this means will become more clear as we see how to create instances of |FAlgebra|.

First we discuss how to define instances of the |Sig| family.
We will need to use GADTs \cite{schrijvers2009complete} to ensure the |t| parameter is set correctly.
As before, the constructors come in two flavors.
For function constructors,
the parameters remain exactly the parameters of the function they correspond to.
The return type, however, depends on the return type of the function.
For type 0 functions (no type family applications in the return type),
the |t| parameter is set to |'[]|.
For example, the function constructor for |Vector|'s |(.*)| function is
\begin{lstlisting}
Sig_dotmul :: Scalar a -> a -> Sig Vector '[] a
\end{lstlisting}
For type 1 functions (one type family application in the return type),
the |t| parameter is the singleton list containing the family's tag.
For example, the return type for |Hilbert|'s |dotProduct| function is |Scalar a|,
so the corresponding function constructor is
\begin{lstlisting}
Sig_dotProduct :: a -> a -> Sig Hilbert '[TScalar] a
\end{lstlisting}
Unlike function constructors, superclass constructors are parametric in their |t| parameter.
Superclass constructors take a single parameter,
which is the |Sig| of the superclass.
If the corresponding constraint does not involve a type family,
then the |t| parameter is the same for the superclass and the returned value.
For example, the |Num a| constraint in the |Vector| instance gets the constructor
\begin{lstlisting}
Sig_Vector_Num :: Sig Num t a -> Sig Vector t a
\end{lstlisting}
If the class constraint does involve a type family,
then we prepend the type family's tag to |t| in the constructor's return type.
For example, the |Floating (Scalar a)| constraint in the |Vector| instance gets the constructor
\begin{lstlisting}
Sig_Vector_Floating
  :: Sig Floating t a -> Sig Vector (TScalar ': t) a
\end{lstlisting}
These changes to the |Sig| type are the core of the differences between heterogeneous and homogeneous |FAlgebra|s.
There will be many changes to all of the other constructions,
but they are all a result of these changes to the signature.

The |runSig| function tells us how to evaluate the signature of an FAlgebra.
It has been split into two functions:
|runSig0| is for running type 0 functions (no type family in the return type),
and |runSig1| is for running type 1 functions (one type family in the return type).
Calling the wrong |run| function will result in a runtime error,
but our construction of the heterogeneous free monad (in Section \ref{sec:het.eval}) will make this impossible.
|runSig0| works just like the homogeneous |runSig|,
but has a more complicated type signature due to the addition of the |t| parameter to |Sig|.
Recall that the |t| type variable represents the type families that have already been applied to the signature;
so when we run the |Sig|, the result needs to reflect those applications.
Thus, the parameter to |runSig0| is |Sig alg t (AppTags t a)|,
and the return type is |AppTags t a|.
Because the |a| type variable appears only inside type family applications,
we need the |proxy a| argument to avoid an ambiguous type.
To implement the |runSig0| function, function constructors recursively call |runSig0| on their argument (with an appropriate |Proxy| parameter representing the type family application in the constraint);
type 0 function constructors are evaluated exactly as in the homogeneous case,
and type 1 function constructors are not evaluated at all because there is no way to make them type check.
For example, here is |Vector|'s |runSig0| function
\begin{lstlisting}
runSig0 _ (Sig_Vector_Num s)
    = runSig0 (Proxy::Proxy a) s
runSig0 _ (Sig_Vector_Floating s)
    = runSig0 (Proxy::Proxy (Scalar a)) s
runSig0 _ (Sig_dotmul s a) = s.*a
\end{lstlisting}
and |Hilbert|'s |runSig0| function
\begin{lstlisting}
runSig0 _ (Sig_Hilbert_Vector s)
    = runSig0 (Proxy::Proxy a) s
\end{lstlisting}
The return type of |runSig1| contains an extra |Tag| applied to it that the content of |Sig| does not have.
This lets us evaluate type 1 functions.
To implement |runSig1|, superclass constructors get called recursively as before,
but this time only type 1 functions can be evaluated,
and type 0 functions will not type check.
Here are the |runSig1| functions for |Vector| and |Hilbert|.
\begin{lstlisting}
runSig1 _ (Sig_Vector_Num s)
    = runSig0 (Proxy::Proxy a) s
runSig1 _ (Sig_Vector_Floating s)
    = runSig0 (Proxy::Proxy (Scalar a)) s

runSig1 _ (Sig_Hilbert_Vector s)
    = runSig1 (Proxy::Proxy a) s
runSig1 _ (Sig_dotproduct a1 a2) = dotproduct a1 a2
\end{lstlisting}

The last component of the |FAlgebra| is the |mapRun| function.
Since our new |Sig| type cannot be made an instance of |Functor|
(see problem 2 in Section \ref{sec:het.probs}),
this function performs the role that |fmap| performed in the homogeneous FAlgebras.
That is, it will allow recursion over the AST.
We will discuss the function in more detail in Section \ref{sec:het.eval} when we discuss evaluating ASTs.
%Before we get to that,
%we'll discuss how to construct and show the ASTs.

\subsection{Constructing the AST}

To construct an AST out of the |Sig| functor requires a heterogeneous version of the free monad.
It is defined as
\begin{lstlisting}
data Free (f::[Tag]->Type->Type) (t::[Tag]) a where
  Free1::f (s ':t)(Free f t a)->Free f (s ':t) a
  Free0::f      t (Free f t a)->Free f      t  a
  Pure ::AppTags t a -> Free f t a
\end{lstlisting}
and the corresponding AST is
\begin{lstlisting}
type AST alg t a = Free (Sig alg) t a
\end{lstlisting}
There are two major changes in the heterogeneous free monad.
First, the kind of the |Free| type constructor has changed.
We've added an additional parameter |t::[Tag]| that represents the type families that need to get applied to |a| to evaluate the syntax tree.
The type signature of the |runAST| function (discussed in detail in Section \ref{sec:het.eval}) makes this clear.
\begin{lstlisting}
runAST :: (FAlgebra alg, alg a)
    => Free (Sig alg) t a -> AppTags t a
\end{lstlisting}
Notice that the return type applies |t| to |a|.
Changing the type of |t| changes the type we get when evaluating the AST.

The second change is that there are now three constructors instead of two.
The |Pure| constructor again represents leaves in the AST.
These leaves now have type |AppTags t a| instead of just |a| in order to accommodate the modified return type of |runAST|.
The |Free0| and |Free1| constructors represent branches in the AST.
These branches correspond to type 0 and type 1 functions respectively.
Notice that in type 1 branches, all of the subtrees have a different type than the tree itself.

An example should illustrate the relationship between the three constructors.
Consider the expression
\begin{lstlisting}
exp (dotProduct (Vec3 1 2 3) (Vec3 2 3 4))
\end{lstlisting}
|Vec3| is an instance of |Hilbert|, so we can create a corresponding AST using |Hilbert|'s |FAlgebra| instance.
\begin{lstlisting}
expr1 :: AST Hilbert '[TScalar] (Vec3 Double)
expr1 = Free0
  ( Sig_Hilbert_Vector
    ( Sig_Vector_Floating
      ( Sig_exp
        ( Free1
          ( Sig_dotProduct
            ( Pure (Vec3 1 2 3)
              :: AST Hilbert '[] (Vec3 Double)
            )
            ( Pure (Vec3 2 3 4)
              :: AST Hilbert '[] (Vec3 Double)
            )
          )
          :: Sig Hilbert '[TScalar]
            (AST Hilbert '[] (Vec3 Double))
        )
        :: AST Hilbert '[TScalar] (Vec3 Double)
      )
      :: Sig Hilbert '[TScalar]
        (AST Hilbert '[TScalar] (Vec3 Double))
    )
    :: Sig Hilbert '[TScalar]
      (AST Hilbert '[TScalar] (Vec3 Double))
  )
\end{lstlisting}
The type signatures on each expression are labeled to emphasize how the type of the tree changes with the application of the |Free0| and |Free1| constructors.
Specifically, because the dot product is a type 1 function (its return type is |Scalar a|),
the |Sig_dotProduct| function gets embedded into the AST using the |Free1| constructor.
This changes the type of the tree by adding |TScalar| to the list of tags.
When we evaluate the resulting tree, we will get a scalar,
so it is now safe to perform scalar operations.
The |exp| function is an example of a scalar operation.
The design of the |Sig_Vector_Floating| constructor lets us embed the |Sig_exp| constructor into the tree only because of the |TScalar| tag generated by |Sig_dotProduct|.
Since |Sig_exp| is a type 0 function,
it is embedded into the tree using the |Free0| constructor.

We can make |AST| an instance of any heterogeneous type class.
This is a two step process.
First, we generate appropriate type instances.
For each type family used in a heterogeneous type class,
define a type instance for |AST| that adds the family's tag to the list of tags.
For example, the |Scalar| of an |AST| is given by
\begin{lstlisting}
type Scalar (AST alg t a) = AST alg (TScalar ': t) a
\end{lstlisting}

%The main difference is that we will need a new |View| class for converting between |Sig|s.
The next step is to define an appropriate |View| class.
The heterogeneous |View| class not only converts the |alg| parameter, but also the |t| parameter.
\begin{lstlisting}
class (FAlgebra alg1, FAlgebra alg2)
    => View alg1 t1 alg2 t2 where
    embedSig
        :: Sig alg1 t1 a -> Sig alg2 t2 a
    unsafeExtractSig
        :: Sig alg2 t2 a -> Sig alg1 t1 a
\end{lstlisting}
%Instances of |View| should satisfy the property that

Armed with these |View| instances, creating heterogeneous type class instances is easy.
It follows the same pattern as the homogeneous case,
except that type 0 functions are embedded in the tree using the |Free0| constructor,
and type 1 functions are embedded using the |Free1| constructor.
The |Vector| instance is shown below.
\begin{lstlisting}
instance
    ( View Vector '[] Num '[]
    , View Vector '[] Floating '[TScalar]
    , View Vector '[] Fractional '[TScalar]
    , View Vector '[] Num '[TScalar]
    ) => Vector (AST alg t a) where
    (.*) s a = Free0 $ embedSig $ Sig_dotmul s a
\end{lstlisting}
And here is the |Hilbert| instance.
\begin{lstlisting}
instance
    ( View Hilbert '[] Vector '[]
    , View Hilbert '[] Num '[]
    , View Hilbert '[] Floating '[TScalar]
    , View Hilbert '[] Fractional '[TScalar]
    , View Hilbert '[] Num '[TScalar]
    => Hilbert (AST alg t a) where
    dotProduct a1 a2
        = Free1 $ embedSig $ Sig_dotProduct a1 a2
\end{lstlisting}

These instances let us easily create ASTs.
The only difference from the homogeneous case is that we must now explicitly tag the type signature to indicate how the return type of the expression relates to the AST's root type.
For example, here's an expression over |Double|s.
\begin{lstlisting}
expr1 :: AST Floating '[] Double
expr1 = (1+2)+3 :: AST Floating '[]
\end{lstlisting}
And here is the same expression expressed as the |Scalar| of |Vec3 Double|.
\begin{lstlisting}
expr2 :: AST Hilbert '[TScalar] (Vec3 Double)
expr2 = (1+2)+3
\end{lstlisting}
We will see more complex examples in the next section's discussion of showing ASTs.

\subsection{Showing the AST}

To convert the heterogeneous AST into a |String|,
we need a |Show| instance for for |Free| and a |Show| instance for each |Sig|.
As is typical for heterogeneous ASTs,
writing these instances is painful,
but using them is easy.

The |Show| instance for |Free| is given below.
\begin{lstlisting}
instance
    ( Show      (AppTags t a)
    , Show      (f t (Free f t a))
    , ShowUntag (f t (Free f t a))
    ) => Show (Free f t a) where
    show (Pure  a ) = show a
    show (Free0 f0) = "("++show f0++")"
    show (Free1 f1) = "("++show f1++")"
\end{lstlisting}
The instance is similar to the homogeneous instance except for the |ShowUntag| type family in the constraints.
This family provides the |Show| instance needed to apply |show| to the |f1| variable.
This variable is declared in the |Free1| constructor,
but because of this constructor's definition,
the type of |f1| is not mentioned anywhere in the instance signature!
The |ShowUntag| function extracts the type of |f1| from instance parameter |t| when it is available and provides a |Show| instance.
When the type cannot be extracted, GHC is able to prove that the pattern match on |Free1| always fails, and so no constraint is needed.
The |ShowUntag| family is defined as:

\newpage
\begin{lstlisting}
type family ShowUntag (f::Type) :: Constraint where
    ShowUntag (f (s ': t) (Free f (s ': t) a))
        = Show (f (s ': t) (Free f t a))
    ShowUntag a = ()
\end{lstlisting}

The |Show| instance for the |Sig| type follows the same pattern as the homogeneous case.
For each function constructor,
simply show the constructor's arguments connected in an appropriate way by the function's name.
For each superclass constructor, recursively call show on the superclass.
As an example, |Vector|'s show instance is given below.
\begin{lstlisting}
instance (Show a, Show (Scalar a))
    => Show (Sig Vector t a) where
    show (Sig_Vector_Num s) = show s
    show (Sig_Vector_Floating s) = show s
    show (Sig_dotmul a1 a2)
        = show a1++".*"++show a2
\end{lstlisting}
Notice that we had to add the |Show (Scalar a)| constraint above because the |a1| variable in the last line has type |Scalar a|.
In general, whenever a function constructor contains a parameter with a type class,
we will need to add a |Show| constraint for the corresponding class.

Unfortunately, we can't yet use these two instances to show an |AST|.
When we call |show| on an expression of type |AST Vector t a|,
the constraint solver looks for a |Show| instance of |Scalar (AST Vector t a)|.
This sends the constraint solver into a loop.
Recall that we defined
\begin{lstlisting}
type Scalar (AST alg t a)
    = AST alg (TScalar ': t) a
\end{lstlisting}
So in order to satisfy the |Show| instance for |AST Vector t a|,
the constraint solver needs a |Show| instance for |AST Vector '[TScalar] a|,
which in turn needs a |Show| instance for |AST Vector '[TScalar,TScalar] a|,
and so on.
The nesting of these |TScalar| tags continues indefinitely.
The solution is to create the following overlapping instance.
\begin{lstlisting}
instance {-#OVERLAPS#-} Show
    (Sig Module (t1 ': t2 ': t3 ': ts) a) where
    show _ = "<<overflow>>"
\end{lstlisting}
Once there are at least three |TScalar|s in the list of tags,
this new instance becomes more specific,
and is thus selected by GHC.
Since this instance has no constraints,
that ends the recursion.
Of course there is nothing special about the choice of three elements in the list above;
the only requirement is that the list be longer than any sequence of type family applications your program actually uses.

Now that these |Show| instances are written,
actually showing expressions is straightforward.
As in the homogeneous case,
you just have to add the appropriate type signature to the expression.
\begin{lstlisting}
ghci> logLogistic 3 :: AST Floating '[] Double
(log ((fromInteger 1)/((fromInteger 1)+(exp
    (negate (fromInteger 3))))))
\end{lstlisting}
This same expression can be shown via the |Hilbert| AST as well.
\begin{lstlisting}
ghci> logLogistic 3 :: AST Hilbert '[TScalar] (Vec3 Double)
(log ((fromInteger 1)/((fromInteger 1)+(exp
    (negate (fromInteger 3))))))
\end{lstlisting}
In order to display functions,
we create the |Var| type as before.
\begin{lstlisting}
newtype Var a = Var String
\end{lstlisting}
When we define values of type |Var|,
we want them to be usable in all expressions regardless of the tag.
This means they need to be parametric in both the |alg| and |t| parameters.
Recall that the argument to the |Pure| construct takes type |AppTags t a|,
so in order to embed a |Var| into an AST using |Pure|,
we need to guarantee that |AppTags t Var~Var|.\footnote{The {\ttfamily mkFAlgebra} function generates type instances for {\ttfamily Var} for all type families used in a heterogeneous class.
All of these instances satisfy the property that {\ttfamily AppTags t Var~Var},
but GHC is unable to prove that all the instances satisfy this property.
That is why the constraint is explicitly added to the type signature of each {\ttfamily varN} variable.
}
\begin{lstlisting}
var1 :: AppTags t Var~Var => AST alg t Var
var1 = Pure $ Var "var1"

var2 :: AppTags t Var~Var => AST alg t Var
var2 = Pure $ Var "var2"

var3 :: AppTags t Var~Var => AST alg t Var
var3 = Pure $ Var "var3"
\end{lstlisting}
%stopzone

\begin{lstlisting}
ghci> logLogistic var1 :: AST Floating '[] Var
(log ((fromInteger 1)/((fromInteger 1)+(exp
    (negate var1)))))
\end{lstlisting}
Recall that |Floating| appeared as a constraint for the |Hilbert| class.
So you might think we could specialize the expression above to the |Hilbert| AST.
\begin{lstlisting}
ghci> logLogistic var1 :: AST Hilbert '[] Var
No instance for
    (View Floating ('[] Tag) Hilbert ('[] Tag))
\end{lstlisting}
%\begin{lstlisting}
%ghci> logLogistic var1 :: AST Hilbert '[] Var
%\end{lstlisting}
%This code give us an error message about the following missing instance.
%\begin{lstlisting}
%View Floating ('[] Tag) Hilbert ('[] Tag)
%\end{lstlisting}
Just because something implements |Hilbert| does not guarantee that it implements |Floating| as well.
It only guarantees that its |Scalar| implements |Floating|.
The following modified expression works just fine.
\begin{lstlisting}
ghci> logLogistic var1 :: AST Hilbert '[TScalar] Var
(log ((fromInteger 1)/((fromInteger 1)+(exp
    (negate var1)))))
\end{lstlisting}
Now we demonstrate this technique works with the |logLoss| function,
which is heterogeneous but not homogeneous.
\begin{lstlisting}
ghci> logLoss var1 var2 :: AST Hilbert '[TScalar] Var
(log ((fromInteger 1)/((fromInteger 1)+(exp
    (negate (dotProduct var1 var2))))))
\end{lstlisting}
And finally, we can have arbitrarily complex expressions in both the scalar and vector section of an expression.
\begin{lstlisting}
ghci> (var1+exp var2).*(var3+var1.*var3)
    :: AST Hilbert '[] Var
((var1+(exp var2)).*(var3+(var1.*var3)))
\end{lstlisting}
Note that in the above expression, |var1| and |var2| are used as scalars whereas |var3| is used as a vector.
 %(var1+exp var2).*var3 :: AST Hilbert '[] Var
%((var1+(exp var2)).*var3)
\subsection{Evaluating the AST}
\label{sec:het.eval}

Our last step in demonstrating the homoiconicity of heterogeneous functions is to evaluate their ASTs.
We will first discuss the |runAST| function.
In so doing we will see the motivation for the |mapRun| function from the definition of the heterogeneous |FAlgebra| type.
Finally, we'll see some examples.

The |runAST| function is shown below.
\begin{lstlisting}
runAST :: forall alg t a. (FAlgebra alg, alg a)
    => Free (Sig alg) t a -> AppTags t a
runAST (Pure  a) = a
runAST (Free0 s)
    = runSig0 (Proxy::Proxy a) $ mapAST runAST s
runAST (Free1 s)
    = runSig1 (Proxy::Proxy a) $ mapAST runAST s
\end{lstlisting}
It has three differences from the homogeneous case.
First, (as we've already discussed)
the type signature is different.
The |t| parameter to |AST| tracks the type represented by the tree.
So the type from running the tree must apply |t| to |a|.
Second, since the free monad has an additional constructor,
the |runAST| function needs an additional clause pattern matching against this constructor.
The clauses for the |Free0| and |Free1| constructors are essentially the same though.
Finally, we use the |mapRun| function instead of |fmap| for recursion.
Recall the signature of |mapRun|.
\begin{lstlisting}
mapRun
  :: (forall s. Free (Sig alg') s a -> AppTags s a)
  -> Sig alg t (Free (Sig alg') t' a)
  -> Sig alg t (AppTags t' a)
\end{lstlisting}
This function uses |Rank2Types| to ensure that the function we are mapping can be applied to any syntax tree no matter what type it represents.

As in the homogeneous case,
when we evalaute an AST for an expression,
we get the same result as if we had just evaluated the expression directly.
\begin{lstlisting}
ghci> logLoss (Vec3 1 2 3) (Vec3 2 3 4)
-2.0611536942919273e-9
\end{lstlisting}

\begin{lstlisting}
ghci> runAST (logLoss (Vec3 1 2 3) (Vec3 2 3 4)
    :: AST Hilbert '[TScalar] (Vec3 Double))
-2.0611536942919273e-9
\end{lstlisting}
We've finally demonstrated that heterogeneous functions are also homoiconic.

\subsection{Boilerplate}

Constructing heterogeneous FAlgebras is a pain.
The \homoiconic library provides a |mkFAlgebra| function in the |Heterogeneous.FAlgebra| module to automate this process.

\section{Conclusion}

The \homoiconic library lets you construct ASTs from type classes.
The construction is easiest for homogeneous type classes and more difficult for heterogeneous type classes.
But in either case, \homoiconic provides Template Haskell functions to shield you from the details and boilerplate.
Your existing Haskell code bases likely include many type classes on which these constructions work.

%\subsection{Transforming heterogeneous functions}
%
%In order to perform program transformations on heterogeneous functions,
%we need two things.
%First, we need convenient way to pattern match.
%The construction is identical to the construction presented in Section \ref{sec:patternmatch}.
%For each function heterogeneous function in a heterogeneous type class,
%we get a pattern that is the name of the function prefixed by |AST_|.
%
%For example, recall the |testFunc1| function we defined before.
%\begin{lstlisting}
%testFunc1 :: Floating a => a -> a
%testFunc1 = log (exp a)
%\end{lstlisting}
%We wrote a program transformation that removed the |log| and |exp| function calls.
%The same program transformation works, but with a modified type signature to account for the heterogeneous ASTs.
%\begin{lstlisting}
%logexpAST3 :: View Floating '[] alg t
    %=> AST alg t a -> AST alg t a
%logexpAST3 (AST_log (AST_exp a)) = a
%\end{lstlisting}
%Finally, we need a way to perform recursion.
%
%\begin{lstlisting}
%mapTrans :: (forall s. View Floating '[] alg s => AST alg s a -> AST alg s a)
    %-> Sig alg t (AST alg t a)
    %-> Sig alg t (AST alg t a)
%mapTrans f = undefined
%\end{lstlisting}
%
%\begin{lstlisting}
%\end{lstlisting}

%\section{Conclusion}
%
%Heterogeneous FAlgebras probably seem scary at this point.

%The \homoiconic package gives Haskell programmers a new metaprogramming tool based on FAlgebras.
%Homogeneous FAlgebras are closely related
%
%Heterogeneous FAlgebras are scary to construct,
%but \homoiconic provides a |mkFAlgebra| function that generates the obnoxious details for you.
%Most of the pain from the heterogeneous FAlgebra type class is due to short comings in the way GHC handles type families.

%It's possible that some future development in the type system will make heterogeneous FAlgebras more pleasant to work with.

%In this paper, we've provided a slight twist on the homogeneous FAlgebra construction that Haskellers know and love and introduced the heterogeneous FAlgebra to the community.
%Both of these structures give us a new form of metaprogr
%Heterogeneous FAlgebras are a pain to define in Haskell.
%But they're not that bad to work with.
%Essentially the only difference is that we must tag our ASTs with the appropriate type families.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%\appendix
%\section{Appendix Title}
%
%This is the text of the appendix, if you need one.
%Most notably, it is not generic.
%
%\acks
%
%Acknowledgments, if needed.
%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\bibliographystyle{abbrvnat}
\bibliography{paper}

\end{document}