How the Piping Operator works

The piping operator is the $ method available on cursors. It is ridiculously simple. You pass it a function, and it calls that function, passing itself as the only argument, then returns whatever the function returns. That's it. The implementation, sans type declarations, is equivalent to:

$(ref) {
    return ref(this);
}

The type declarations are important, of course: the things being passed around must be cursors, though the input and output cursors can refer to different types:

$<S2, A2>(ref: (outer: Cursor<S, A>) => Cursor<S2, A2>): Cursor<S2, A2>;

The parameter is called ref because reference definitions are ideal for passing in.

Why bother with such a simple thing? So we can write easy-to-read expressions that navigate down a hierarchy. Suppose a Shop has a collection Shelves of Shelf objects, each having a collection Books of Book objects, each having a title.

Without piping, we have to write inside-out expressions. Here, shop is the starting point, yet appears in the middle!

const book = Book.title(
                Books.at(
                    Shelf.books(
                        Shelves.at(
                            Shop.shelves(shop),
                            13
                        )
                    ), 
                    832
                )
            );

With piping, we "send" the input through a pipeline of operators, and it's self-explanatory:

const title = shop.$(Shop.shelves)
                  .$(Shelves.at(13))
                  .$(Shelf.books)
                  .$(Books.at(832))
                  .$(Book.title);

results matching ""

    No results matching ""