Solution to servant API type indentation problem

Posted on 2017-03-15 by Oleg Grenrus servant

This post is a literate Haskell file: so there are few imports, and {-# LANGUAGE TypedKitchenSink #-}.

#Problem

How you indent your servant api types?

There seems to be an unsolvable aesthetic vs. diff-friendly problem!

#Solution

Let's add a type-family!

With the help of ListApi, we can reduce the indentation problem to how we indent (type-level) lists:

The API and previously defined types are the same:

#Follow-up

Yet to write the Server API, we still need to use :<|>. The problem is not solved properly yet. There is generic client in servant-client (PR#640), and we can use the same idea for server part too: we need one more type family and generics-sop:

This function is written in the infamous banzai mode, to convince GHC the program is well-typed. The Proxy argument is not obviously required, but the following code would be ambiguous without it. The Shape parameter in step0 is needed because GHC cannot reason backwards ServerMap xs ~ '[]xs ~ '[] (ServerMap is injective only shallowly, Server isn't injective!). We need two steps, because going directly from NP I (ServerMap ys) to Server (ListApi ys) would require to deal with two type-families at once, and GHC had Also, step1 highlights the question: should we have a type for an identity element of :<|> operation?

#An example

With the help of ListApi and listApiServer, we could define the server implementation in a neat way, IMO:

If you experiment with the code and try to change the types in ApiImpl fields, then the check "test" will catch them. It seems, that errors generated from type-checking check are way more to the point than type-errors in "classic" serve api $ endpoint1 :<|> endpoint2 :<|> ... approach.

I tend to have small wrappers around actual implementation of endpoints, (i.e. I do write apiFoo which calls businessFoo, which knows little or nothing about the web) so the ApiImpl is the only additional boilerplate.

Would this be useful? Give it a spin! Please comment either directly to me (tweet) or to servant issue.


You can run this file with

fetch the source from https://gist.github.com/phadej/06e0ce32e790fdab63b119fcbad357f5

P.S. Someone, please fix DataKinds syntax highlighting in whatever pandoc uses!

Site proudly generated by Hakyll