The third type of embedding is called class-based shallow embedding and has the
advantages of both shallow and deep
embedding~\cite{svenningsson_combining_2012}. In class-based shallow embedding
the language constructs are defined as type classes. This language is shown
with the new method in Listing~\ref{lst:exclassshallow}.

This type of embedding inherits the ease of adding views from shallow
embedding. A view is just a different data type implementing one or more of the
type classes as shown in the aforementioned Listing where an evaluator and a
pretty printer are implemented.

Just as with \glspl{GADT}, type safety is guaranteed in deep embedding. Type
constraints are enforced through phantom types. One can add as many phantom
types as necessary. Lastly, extensions can be added easily, just as in
shallow embedding. When an extension is made in an existing class, all views
must be updated accordingly to prevent possible runtime errors. When an
extension is added in a new class, this problem does not arise and views can
choose to implement only parts of the collection of classes.

In contrast to deep embedding, it is very well possible to have multiple views
applied on the same expression. This is also shown in the following listing.

\begin{lstlisting}[label={lst:exclassshallow},%
	caption={A minimal class based shallow \gls{EDSL}}]
:: Env   = ...            // Some environment
:: Evaluator a = Evaluator (Env -> a)
:: PrettyPrinter a = PP String

class intArith where
	lit   :: t -> v t             | toString t
	add   :: (v t) (v t) -> (v t) | + t
	minus :: (v t) (v t) -> (v t) | - t

class boolArith where
	and :: (v Bool) (v Bool) -> (v Bool)
	eq  :: (v t)    (v t)    -> (v Bool) | == t

instance intArith Evaluator where
	lit x   = Evaluator \e->x
	add x y = Evaluator ...

instance intArith PrettyPrinter where
	lit x   = PP $ toString x
	add x y = PP $ x +++ "+" +++ y
	...

...

Start :: (PP String, Bool)
Start = (print e0, eval e0)
where
	e0 :: a Bool | intArith, boolArith a
	e0 = eq (lit 42) (lit 21 +. lit 21)

	print (PP p) = p
	eval (Evaluator e) env = e env
\end{lstlisting}
