about summary refs log tree commit diff
path: root/users/tazjin/presentations/servant-2016/slides.tex
blob: d5947eb9421afa56dcc3ec13b1e0adea9a40a0b2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
\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}