[collection notes] HTTP Server Basics In ReasonML

I just watched this ReasonML collection from Murphy Randle

https://egghead.io/playlists/making-an-http-server-in-reasonml-on-top-of-node-js-dab086a2

It goes over

  • async/await in Reason (how to unnest a bunch of JS promises with a bs-let extension)
  • encoding/decoding json
  • building a small express server

I took some notes here:

https://www.ianjones.us/reasonml-async-await

If you’v watched the collection, what did you take away from it?

3 Likes

The killer thing in this collection for me is reasonml-labs/decco. I currently use @glennsl/bs-json for manual JSON encoding and decoding. I had never heard of this ppx, but I think I’m about to switch!

My takeaway from the reasonml-labs/bs-let approach in the first video, though, is that I feeeeel like you can get a little more freedom/expressivity in other ways that feel pretty smooth in Reason (and even in JS, I would argue).

To take the example from the bs-let docs, for instance, I would use BsAbstract to give me access to all of the capabilities that Option has to offer, where let%Option only gives me access to its map function (or so it appears to me).

type user = { . "info": option({. "address": option({. "street": option(string)})})};

let getStreet = (maybeUser: option(user)): option(string) =>
  BsAbstract.Option.Infix.(
    maybeUser
    >>= (user => user##info)
    >>= (info => info##address)
    >>= (address => address##street)
    <#> Js.String.toUpperCase
  );

// or even with Belt.Option
let getStreet_2 = (maybeUser: option(user)): option(string) =>
  Belt.Option.(
    maybeUser
    ->flatMap(user => user##info)
    ->flatMap(info => info##address)
    ->flatMap(address => address##street)
    ->map(Js.String.toUpperCase)
  );

tl;dr: all that nesting is optional with proper monads (even fake ones like Promise)

2 Likes