Customize Operator in ReasonML

2018-07-09 • 1 min read
#reasonml#customize#operator

This topic is inspired by the post: https://twitter.com/_astrocoders/status/1013466409156870147

It could be messy when writing a lot of if-else in your code. It could be something like the following:

let myObj = Js.Dict.empty();
if (1 == 2) {
Js.Dict.set(myObj, "title", "myTitle");
};
if (true == true) {
Js.Dict.set(myObj, "id", 123);
};
view raw OldFormat.re hosted with ❤ by GitHub

The code looks not so elegant although it still works.

Alternatively, according to this tweet, we know that we can customize operators in ReasonML. Therefore, we could utilize this feature and implement something like this:

open CustomizedOperator.Op; /* In order to use operator from another file. */
Js.Dict.empty()
>>= ((obj) => { Js.Dict.set(obj, "title", "myTitle"); obj}, 1 == 2)
>>= ((obj) => { Js.Dict.set(obj, "id", 123); obj}, true = true);
/*
Result will be:
{id: 123}
*/
view raw App.re hosted with ❤ by GitHub
module Op = {
let (>>=) = (obj, (func, cond)) => cond ? func(obj) : obj;
};
/* Inspired by: https://twitter.com/_astrocoders/status/1013466409156870147 */

We could either declare our own customized operator in the same file or put it in another util file. From the above example, I make >>= as a function that takes an object, a function, and a condition. It basically evaluates the given condition: if it’s true, then apply the function to the object; otherwise, it returns the original object.

In App.re , we could use this customized operator (similar to the pipe operator |>) elegantly to pass down the object all the way and also use it directly as an input to another function.

e.g., obj >>= (fun1, cond1) >>= (fun2, cond2) |> stringifyObjToJson

There are more examples here: https://github.com/Risto-Stevcev/bs-abstract/ if you want to use others’ definition of operators.

This article is originally published on my Medium.