From 009888e1edd6de64adc07364852031b03997ca40 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Mon, 1 Feb 2016 15:59:00 +0100 Subject: Add slides --- Makefile | 8 ++++ README.md | 3 ++ slides.pdf | Bin 0 -> 71174 bytes slides.pdfpc | 75 ++++++++++++++++++++++++++++++++ slides.tex | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 223 insertions(+) create mode 100644 Makefile create mode 100644 README.md create mode 100644 slides.pdf create mode 100644 slides.pdfpc create mode 100644 slides.tex diff --git a/Makefile b/Makefile new file mode 100644 index 000000000000..96115ec2cbfc --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +all: slides + +slides: + lualatex --shell-escape slides.tex + +clean: + rm -f slides.aux slides.log slides.nav \ + slides.out slides.toc slides.snm diff --git a/README.md b/README.md new file mode 100644 index 000000000000..ebeca2be8c21 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +These are the slides for my presentation about servant at Oslo Haskell. + +www.meetup.com/Oslo-Haskell/events/227107530/ diff --git a/slides.pdf b/slides.pdf new file mode 100644 index 000000000000..842a667e1bcc Binary files /dev/null and b/slides.pdf differ diff --git a/slides.pdfpc b/slides.pdfpc new file mode 100644 index 000000000000..ed46003768c0 --- /dev/null +++ b/slides.pdfpc @@ -0,0 +1,75 @@ +[file] +slides.pdf +[font_size] +10897 +[notes] +### 1 +13### 2 +Let's talk about servant, which is several things: +API description DSL, we'll speak about how this DSL works +and why it's at the type level + +Interpretations of the types resulting from that DSL, for example in +web servers or API clients + +Servant is commonly used or implementing services with APIs, or for accessing +other APIs with a simple, typed client +### 3 +Why type-level DSLs? +Type-level DSL: express *something*, e.g. endpoints of API, on type level by combining types. Types can be uninhabited + +Phil Wadler's: expression problem: things should be extensible both in the cases of a type, and in the functions operating on the type +Normal data types: can't add new constructors easily +Servant lifts thisup to simply allow the declaration of new types that can be included in the DSL, and new interpretations that can be attached to the types through typeclasses + +APIs become first-class citizens, can pass them around, combine them etc, they are separate from interpretations such as server implementations. In contrast, in most webframeworks, API declaration is implicit + +(Mention previous attemps at type-safe web, Yesod / web-routes + boomerang etc) +### 4 +Three extensions are necessary: +TypeOperators lets us use infix operators on the type level as constructors +DataKinds promotes new type declarations to the kind level, makes type-level literals (strings and natural numbers) available, lets us use type-level lists and pairs in combination with typeoperators +TypeFamilies: Type-level functions, map one set of types to another, come in two forms (type families, non-injective; data families, injective), more powerful than associated types +### 5 +Here you can see servant's general syntax, we define an API type as a simple alias of some other type combinations +strings are type-level strings, not actually values, represent path elements +endpoints are separated by :<|>, all endpoints end in a method with content types and return types +Capture captures path segments, but there are other combinators, for example for headers +Everything that is used from the request is expressed in types, enforcing checkability, no "escape hatch" inside handlers to get request +Every combinator has associated interpretations through typeclasses +### 6 +Explain type alias, point out Capture +Server is a type level function (type family), as mentioned earlier +### 7 +If we expand server (in ghci with kind!) we can see the actual type of the +function +### 8 +Lets speak about some interpretations of these things +### 9 +Servant server is the main interpretation that people are interested in, it's used +for taking a type specification and creating a server from it +Based on WAI, the web application interface, common abstraction for web servers which came out of the Yesod project. Implemented by the web server warp, which Yesod runs on +### 10 +Explain snippet, path gets removed from server type (irrelevant for handler), +route extracts string to value level +### 11 +Explain echo server quickly +### 12 +servant client allows generation of Haskell functions that query the API with the same types +this makes for easy to use RPC for example +### 13 +A lot of other interpretations exist for all kinds of things, mock servers for testing, foreign functions in various languages, documentation ... +### 14 +Demo! +1. Go quickly through code +2. Run server, query with curl +3. Open javascript function +4. Show JS code in the thing +5. Open the map itself +6. Open GHCi, use client +7. Generate docs +### 15 +Conclusion +Servant is pretty good, it's very easy to get started and it's great to raise the level of things that the compiler can tell you about when you do them wrong. +### 16 +Drawbacks. diff --git a/slides.tex b/slides.tex new file mode 100644 index 000000000000..d5947eb9421a --- /dev/null +++ b/slides.tex @@ -0,0 +1,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} -- cgit 1.4.1 From ff30233b240fa3438e10729e07300014d921bb55 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Thu, 4 Feb 2016 12:43:13 +0100 Subject: Updated README with information about the meetup --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ebeca2be8c21..8cfb04a42417 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ -These are the slides for my presentation about servant at Oslo Haskell. +These are the slides for my presentation about [servant][] at [Oslo Haskell][]. -www.meetup.com/Oslo-Haskell/events/227107530/ +A full video recording of the presentation is available [on Vimeo][]. + +[servant]: https://haskell-servant.github.io/ +[Oslo Haskell]: http://www.meetup.com/Oslo-Haskell/events/227107530/ +[on Vimeo]: https://vimeo.com/153901805 -- cgit 1.4.1 From aecd6fda703e1904e3fb366161f54708eb2118ae Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Sat, 21 Dec 2019 00:34:11 +0000 Subject: chore(servant-presentation): Prepare for depot merge --- Makefile | 8 -- README.md | 7 -- presentations/servant-2016/Makefile | 8 ++ presentations/servant-2016/README.md | 7 ++ presentations/servant-2016/slides.pdf | Bin 0 -> 71174 bytes presentations/servant-2016/slides.pdfpc | 75 +++++++++++++++++ presentations/servant-2016/slides.tex | 137 ++++++++++++++++++++++++++++++++ slides.pdf | Bin 71174 -> 0 bytes slides.pdfpc | 75 ----------------- slides.tex | 137 -------------------------------- 10 files changed, 227 insertions(+), 227 deletions(-) delete mode 100644 Makefile delete mode 100644 README.md create mode 100644 presentations/servant-2016/Makefile create mode 100644 presentations/servant-2016/README.md create mode 100644 presentations/servant-2016/slides.pdf create mode 100644 presentations/servant-2016/slides.pdfpc create mode 100644 presentations/servant-2016/slides.tex delete mode 100644 slides.pdf delete mode 100644 slides.pdfpc delete mode 100644 slides.tex diff --git a/Makefile b/Makefile deleted file mode 100644 index 96115ec2cbfc..000000000000 --- a/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -all: slides - -slides: - lualatex --shell-escape slides.tex - -clean: - rm -f slides.aux slides.log slides.nav \ - slides.out slides.toc slides.snm diff --git a/README.md b/README.md deleted file mode 100644 index 8cfb04a42417..000000000000 --- a/README.md +++ /dev/null @@ -1,7 +0,0 @@ -These are the slides for my presentation about [servant][] at [Oslo Haskell][]. - -A full video recording of the presentation is available [on Vimeo][]. - -[servant]: https://haskell-servant.github.io/ -[Oslo Haskell]: http://www.meetup.com/Oslo-Haskell/events/227107530/ -[on Vimeo]: https://vimeo.com/153901805 diff --git a/presentations/servant-2016/Makefile b/presentations/servant-2016/Makefile new file mode 100644 index 000000000000..96115ec2cbfc --- /dev/null +++ b/presentations/servant-2016/Makefile @@ -0,0 +1,8 @@ +all: slides + +slides: + lualatex --shell-escape slides.tex + +clean: + rm -f slides.aux slides.log slides.nav \ + slides.out slides.toc slides.snm diff --git a/presentations/servant-2016/README.md b/presentations/servant-2016/README.md new file mode 100644 index 000000000000..8cfb04a42417 --- /dev/null +++ b/presentations/servant-2016/README.md @@ -0,0 +1,7 @@ +These are the slides for my presentation about [servant][] at [Oslo Haskell][]. + +A full video recording of the presentation is available [on Vimeo][]. + +[servant]: https://haskell-servant.github.io/ +[Oslo Haskell]: http://www.meetup.com/Oslo-Haskell/events/227107530/ +[on Vimeo]: https://vimeo.com/153901805 diff --git a/presentations/servant-2016/slides.pdf b/presentations/servant-2016/slides.pdf new file mode 100644 index 000000000000..842a667e1bcc Binary files /dev/null and b/presentations/servant-2016/slides.pdf differ diff --git a/presentations/servant-2016/slides.pdfpc b/presentations/servant-2016/slides.pdfpc new file mode 100644 index 000000000000..ed46003768c0 --- /dev/null +++ b/presentations/servant-2016/slides.pdfpc @@ -0,0 +1,75 @@ +[file] +slides.pdf +[font_size] +10897 +[notes] +### 1 +13### 2 +Let's talk about servant, which is several things: +API description DSL, we'll speak about how this DSL works +and why it's at the type level + +Interpretations of the types resulting from that DSL, for example in +web servers or API clients + +Servant is commonly used or implementing services with APIs, or for accessing +other APIs with a simple, typed client +### 3 +Why type-level DSLs? +Type-level DSL: express *something*, e.g. endpoints of API, on type level by combining types. Types can be uninhabited + +Phil Wadler's: expression problem: things should be extensible both in the cases of a type, and in the functions operating on the type +Normal data types: can't add new constructors easily +Servant lifts thisup to simply allow the declaration of new types that can be included in the DSL, and new interpretations that can be attached to the types through typeclasses + +APIs become first-class citizens, can pass them around, combine them etc, they are separate from interpretations such as server implementations. In contrast, in most webframeworks, API declaration is implicit + +(Mention previous attemps at type-safe web, Yesod / web-routes + boomerang etc) +### 4 +Three extensions are necessary: +TypeOperators lets us use infix operators on the type level as constructors +DataKinds promotes new type declarations to the kind level, makes type-level literals (strings and natural numbers) available, lets us use type-level lists and pairs in combination with typeoperators +TypeFamilies: Type-level functions, map one set of types to another, come in two forms (type families, non-injective; data families, injective), more powerful than associated types +### 5 +Here you can see servant's general syntax, we define an API type as a simple alias of some other type combinations +strings are type-level strings, not actually values, represent path elements +endpoints are separated by :<|>, all endpoints end in a method with content types and return types +Capture captures path segments, but there are other combinators, for example for headers +Everything that is used from the request is expressed in types, enforcing checkability, no "escape hatch" inside handlers to get request +Every combinator has associated interpretations through typeclasses +### 6 +Explain type alias, point out Capture +Server is a type level function (type family), as mentioned earlier +### 7 +If we expand server (in ghci with kind!) we can see the actual type of the +function +### 8 +Lets speak about some interpretations of these things +### 9 +Servant server is the main interpretation that people are interested in, it's used +for taking a type specification and creating a server from it +Based on WAI, the web application interface, common abstraction for web servers which came out of the Yesod project. Implemented by the web server warp, which Yesod runs on +### 10 +Explain snippet, path gets removed from server type (irrelevant for handler), +route extracts string to value level +### 11 +Explain echo server quickly +### 12 +servant client allows generation of Haskell functions that query the API with the same types +this makes for easy to use RPC for example +### 13 +A lot of other interpretations exist for all kinds of things, mock servers for testing, foreign functions in various languages, documentation ... +### 14 +Demo! +1. Go quickly through code +2. Run server, query with curl +3. Open javascript function +4. Show JS code in the thing +5. Open the map itself +6. Open GHCi, use client +7. Generate docs +### 15 +Conclusion +Servant is pretty good, it's very easy to get started and it's great to raise the level of things that the compiler can tell you about when you do them wrong. +### 16 +Drawbacks. diff --git a/presentations/servant-2016/slides.tex b/presentations/servant-2016/slides.tex new file mode 100644 index 000000000000..d5947eb9421a --- /dev/null +++ b/presentations/servant-2016/slides.tex @@ -0,0 +1,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} diff --git a/slides.pdf b/slides.pdf deleted file mode 100644 index 842a667e1bcc..000000000000 Binary files a/slides.pdf and /dev/null differ diff --git a/slides.pdfpc b/slides.pdfpc deleted file mode 100644 index ed46003768c0..000000000000 --- a/slides.pdfpc +++ /dev/null @@ -1,75 +0,0 @@ -[file] -slides.pdf -[font_size] -10897 -[notes] -### 1 -13### 2 -Let's talk about servant, which is several things: -API description DSL, we'll speak about how this DSL works -and why it's at the type level - -Interpretations of the types resulting from that DSL, for example in -web servers or API clients - -Servant is commonly used or implementing services with APIs, or for accessing -other APIs with a simple, typed client -### 3 -Why type-level DSLs? -Type-level DSL: express *something*, e.g. endpoints of API, on type level by combining types. Types can be uninhabited - -Phil Wadler's: expression problem: things should be extensible both in the cases of a type, and in the functions operating on the type -Normal data types: can't add new constructors easily -Servant lifts thisup to simply allow the declaration of new types that can be included in the DSL, and new interpretations that can be attached to the types through typeclasses - -APIs become first-class citizens, can pass them around, combine them etc, they are separate from interpretations such as server implementations. In contrast, in most webframeworks, API declaration is implicit - -(Mention previous attemps at type-safe web, Yesod / web-routes + boomerang etc) -### 4 -Three extensions are necessary: -TypeOperators lets us use infix operators on the type level as constructors -DataKinds promotes new type declarations to the kind level, makes type-level literals (strings and natural numbers) available, lets us use type-level lists and pairs in combination with typeoperators -TypeFamilies: Type-level functions, map one set of types to another, come in two forms (type families, non-injective; data families, injective), more powerful than associated types -### 5 -Here you can see servant's general syntax, we define an API type as a simple alias of some other type combinations -strings are type-level strings, not actually values, represent path elements -endpoints are separated by :<|>, all endpoints end in a method with content types and return types -Capture captures path segments, but there are other combinators, for example for headers -Everything that is used from the request is expressed in types, enforcing checkability, no "escape hatch" inside handlers to get request -Every combinator has associated interpretations through typeclasses -### 6 -Explain type alias, point out Capture -Server is a type level function (type family), as mentioned earlier -### 7 -If we expand server (in ghci with kind!) we can see the actual type of the -function -### 8 -Lets speak about some interpretations of these things -### 9 -Servant server is the main interpretation that people are interested in, it's used -for taking a type specification and creating a server from it -Based on WAI, the web application interface, common abstraction for web servers which came out of the Yesod project. Implemented by the web server warp, which Yesod runs on -### 10 -Explain snippet, path gets removed from server type (irrelevant for handler), -route extracts string to value level -### 11 -Explain echo server quickly -### 12 -servant client allows generation of Haskell functions that query the API with the same types -this makes for easy to use RPC for example -### 13 -A lot of other interpretations exist for all kinds of things, mock servers for testing, foreign functions in various languages, documentation ... -### 14 -Demo! -1. Go quickly through code -2. Run server, query with curl -3. Open javascript function -4. Show JS code in the thing -5. Open the map itself -6. Open GHCi, use client -7. Generate docs -### 15 -Conclusion -Servant is pretty good, it's very easy to get started and it's great to raise the level of things that the compiler can tell you about when you do them wrong. -### 16 -Drawbacks. diff --git a/slides.tex b/slides.tex deleted file mode 100644 index d5947eb9421a..000000000000 --- a/slides.tex +++ /dev/null @@ -1,137 +0,0 @@ -\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} -- cgit 1.4.1