Change-Id: I72b25680e7167c3a55477111c28b1d4936c60e2c Reviewed-on: https://cl.tvl.fyi/c/depot/+/606 Reviewed-by: tazjin <mail@tazj.in>
		
			
				
	
	
		
			137 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			TeX
		
	
	
	
	
	
			
		
		
	
	
			137 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			TeX
		
	
	
	
	
	
\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}
 |