Pipe-first
BuckleScript has a special |.
(or ->
for Reason) pipe syntax for dealing with various situations. This operator has many uses.
#Pipelining
The pipe takes the item on the left and put it as the first argument of the item on the right. Great for building pipelines of data processing:
REa
->foo(b)
->bar
is equal to
REbar(foo(a, b))
#JS Method Chaining
JavaScript's APIs are often attached to objects, and often chainable, like so:
JSconst result = [1, 2, 3].map(a => a + 1).filter(a => a % 2 === 0);
asyncRequest().setWaitDuration(4000).send();
Assuming we don't need the chaining behavior above, we'd bind to each case this using bs.send
from the previous section:
RE[@bs.send] external map : (array('a), 'a => 'b) => array('b) = "map";
[@bs.send] external filter : (array('a), 'a => 'b) => array('b) = "filter";
type request;
external asyncRequest: unit => request = "asyncRequest";
[@bs.send] external setWaitDuration: (request, int) => request = "setWaitDuration";
[@bs.send] external send: request => unit = "send";
You'd use them like this:
RElet result = filter(map([|1, 2, 3|], a => a + 1), a => a mod 2 == 0);
send(setWaitDuration(asyncRequest(), 4000));
This looks much worse than the JS counterpart! Now we need to read the actual logic "inside-out". We also cannot use the |>
operator here, since the object comes first in the binding. But |.
and ->
work!
RElet result = [|1, 2, 3|]
->map(a => a + 1)
->filter(a => a mod 2 === 0);
asyncRequest()->setWaitDuration(400)->send;
#Pipe Into Variants
This works:
RElet result = name->preprocess->Some
We turn this into:
RElet result = Some(preprocess(name))