Building a Web app with FP - Part I - Servant

Howdy! I’m writing a series on building from scratch a web app with FP.

There will be articles about packaging with Nix, running on NixOS, configuring with Dhall, testing with Ghcid, creating a web page with Elm, and maybe more fun stuff.

To make the read of code easier, I’ve made kamo, which in a nutshell helps writing technical articles with diffs.

If you’ve read this first article, I’m curious about what you think about kamo. Did you find it useful to understand the code? Anything you didn’t like about it?


You probably want to change the title and move the link into the body of your message, right now it’s not clickable.

I liked the article and am interested in reading the next posts!

I also liked the diff idea and tried to use it in the past without much success. But currently the side by side view isn’t working very well because the windows are too small.

I’d recommend either adopting a formatting style that keep lines short (probably good anyway especially for articles) to the point where one doesn’t need to scroll, or (/and) display the changes inline instead of side by side.

Another thing, I think the article kinda assumes that the reader already knows servant and advanced type system features - it assume the user understands that it’s possible to create types which represent APIs, what the servant combinators look like, etc without explaining those stuff which are fairly non trivial.

If the point is to write an article for people who have some sort of an understanding of servant that’s fine, but for people who don’t understand it yet, explaining what’s written and how things work will make it more accessible.

1 Like

I changed the title and it’s much better indeed :slight_smile:

Yes, I try to not dive too much into the details otherwise it’s going to look like more like a book rather than a blog post (there is a lot to cover, type level, monad & monad transformer…). But maybe I should give a bit more details.

That’s curious… Would you mind sharing your OS and browser (or perhaps are you browsing on your mobile?)? I made it so the whole diff would be displayed without having to scroll. But I guess my css skills failed me again :sweat_smile:

Anyways, thanks a lot for the feedback!

1 Like

Of course, I’m not saying you should cover Haskell from first principles, monads and monad transformers are not novel in Haskell world and there are many articles and books explaining them (you even linked one), but servant and type level programming (for servant) might not be as common.

Think about who you are writing these articles for and what you think they understand - maybe your target audience is familiar with enough type level programming and read about servant in the past even if they never wrote servant code before and they will not have any problem following along (I’m in this group), but if you are targeting people who don’t know what servant is or are not really familiar with type level programming, maybe some information will be required, maybe even links to the right articles.

I’ve read it on mobile! (firefox). indeed on my 1440p desktop monitor fullscreen only a bit of scrolling was needed, if I cut it in half (as I normally do) we have about 700px for two screens side by side and that’s not much.

I agree, re-reading it now and it feels like I sometimes target beginners, sometimes intermediate users. Thanks for the advice, I’ll try to focus on a single audience :slight_smile:

edit: I have updated the article with your advice in mind :+1:


Had some time to read this. Seems good so far, and I like how you made it obvious which lines were changed. Really useful.

Package issue

sekun@pop-os:~/Projects/hweather$ stack install

Error: While constructing the build plan, the following exceptions were encountered:

In the dependencies for hweather-
    servant-flatten needed, but the stack configuration has no specified version  (latest matching version is 0.2)
needed since hweather is a build target.

Some different approaches to resolving this:

  * Recommended action: try adding the following to your extra-deps in /home/sekun/Projects/hweather/stack.yaml:

- servant-flatten-0.2@sha256:276896f7c5cdec5b8f8493f6205fded0cc602d050b58fdb09a6d7c85c3bb0837,1234

I followed its recommendation but I’m not sure if I’m supposed to cause I don’t know what stack trickery is required since I’ve never used it before. It seems to be fine.

It works!


So with this one I was kinda confused with for a bit since I wasn’t sure exactly what the curl request would look like for PUT /api/weather/:location. It doesn’t mention how the user could try this out, only for the GET request.

To be more specific, I was confused with how ReqBody translates to the actual JSON body. Servant’s docs had a User object which I assumed that it would just be a JSON object but was confused with what the key of the JSON object would be in this case. Turns out, the entire thing was just a string! Well, figures hahah.

:<|> ReqBody '[JSON] String :> Put '[JSON] String

So turns out it was just this:

> curl -H "Content-Type: application/json" -X PUT -d '"sunny"' localhost:8888/api/weather/Paris
# "sunny"
1 Like

Oh yes, you’re right, I’ll edit the post to add the curl command for the PUT request as well :slight_smile:
And Yes, also correct for the stack thing. I actually had the same warning but because it depends on which stack resolver you’re using, I didn’t explain it :slight_smile:

I’ve made a repo with all the branches (i.e: branch part-I == article part-I) here if you some details are missing from the article (like the stack thing)!

1 Like

:relieved::relieved::relieved::relieved::relieved::relieved::relieved: monke :relieved::relieved::relieved::relieved::relieved::relieved::relieved:

1 Like

Great post though! Thanks too for referencing resources for the harder topics. I’m excited to read the next one when I get some more free time. :smiley:

1 Like

It means a lot, thanks you sekun :slight_smile: