Skip to main content

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:

a
|. foo b
|. bar

is equal to

bar(foo a b)

JS Method Chaining​

JavaScript's APIs are often attached to objects, and often chainable, like so:

const 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:

external map : 'a array -> ('a -> 'b) -> 'b array = "map" [@@bs.send]
external filter : 'a array -> ('a -> 'b) -> 'b array = "filter" [@@bs.send]

type request
external asyncRequest: unit -> request = "asyncRequest"
external setWaitDuration: request -> int -> request = "setWaitDuration" [@@bs.send]
external send: request -> unit = "send" [@@bs.send]

You'd use them like this:

let result = filter (map [|1; 2; 3|] (fun a -> a + 1)) (fun a -> a mod 2 = 0)

let () = 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!

let result = [|1; 2; 3|]
|. map(fun a -> a + 1)
|. filter(fun a -> a mod 2 == 0)

let () = asyncRequest () |. setWaitDuration 400 |. send

Pipe Into Variants​

This works:

let result = name |. preprocess |. Some

We turn this into:

let result = Some(preprocess(name))