blob: d5947eb9421afa56dcc3ec13b1e0adea9a40a0b2 (
plain) (
tree)
|
|
\documentclass[12pt]{beamer}
\usetheme{metropolis}
\usepackage{minted}
\newenvironment{code}{\ttfamily}{\par}
\title{servant}
\subtitle{Defining web APIs at the type-level}
\begin{document}
\metroset{titleformat frame=smallcaps}
\setminted{fontsize=\scriptsize}
\maketitle
\section{Introduction}
\begin{frame}{Type-level DSLs?}
\begin{itemize}
\item (Uninhabited) types with attached ``meaning''
\item The Expression Problem (Wadler 1998)
\item API representation and interpretation are separated
\item APIs become first-class citizens
\end{itemize}
\end{frame}
\begin{frame}{Haskell extensions}
\begin{itemize}
\item TypeOperators
\item DataKinds
\item TypeFamilies
\end{itemize}
\end{frame}
\begin{frame}[fragile]{A servant example}
\begin{minted}{haskell}
type PubAPI = "pubs" :> Get ’[JSON] [Pub]
:<|> "pubs" :> "tagged"
:> Capture "tag" Text
:> Get ’[JSON] [Pub]
\end{minted}
\end{frame}
\begin{frame}[fragile]{Computed types}
\begin{minted}{haskell}
type TaggedPubs = "tagged" :> Capture "tag" Text :> ...
taggedPubsHandler :: Server TaggedPubs
taggedPubsHandler tag = ...
\end{minted}
\end{frame}
\begin{frame}[fragile]{Computed types}
\begin{minted}{haskell}
type TaggedPubs = "tagged" :> Capture "tag" Text :> ...
taggedPubsHandler :: Server TaggedPubs
taggedPubsHandler tag = ...
Server TaggedPubs ~
Text -> EitherT ServantErr IO [Pub]
\end{minted}
\end{frame}
\section{Interpretations}
\begin{frame}{servant-server}
The one everyone is interested in!
\begin{itemize}
\item Based on WAI, can run on warp
\item Interprets combinators with a simple \texttt{HasServer c} class
\item Easy to use!
\end{itemize}
\end{frame}
\begin{frame}[fragile]{HasServer ...}
\begin{minted}{haskell}
instance (KnownSymbol path, HasServer sublayout)
=> HasServer (path :> sublayout) where
type ServerT (path :> sublayout) m = ServerT sublayout m
route ...
where
pathString = symbolVal (Proxy :: Proxy path)
\end{minted}
\end{frame}
\begin{frame}[fragile]{Server example}
\begin{minted}{haskell}
type Echo = Capture "echo" Text :> Get ’[PlainText] Text
echoAPI :: Proxy Echo
echoAPI = Proxy
echoServer :: Server Echo
echoServer = return
\end{minted}
\end{frame}
\begin{frame}{servant-client}
\begin{itemize}
\item Generates Haskell client functions for API
\item Same types as API specification: For RPC the whole ``web layer'' is abstracted away
\item Also easy to use!
\end{itemize}
\end{frame}
\begin{frame}{servant-docs, servant-js ...}
Many other interpretations exist already, for example:
\begin{itemize}
\item Documentation generation
\item Foreign function export (e.g. Elm, JavaScript)
\item Mock-server generation
\end{itemize}
\end{frame}
\section{Demo}
\section{Conclusion}
\begin{frame}{Drawbacks}
\begin{itemize}
\item Haskell has no custom open kinds (yet)
\item Proxies are ugly
\item Errors can be a bit daunting
\end{itemize}
\end{frame}
\begin{frame}{Questions?}
Ølkartet: github.com/tazjin/pubkartet \\
Slides: github.com/tazjin/servant-presentation
@tazjin
\end{frame}
\end{document}
|