functional-programmingfluture

Creating a composePipe function for Futures from Fluture


I wanted to make a compose function for piping and im stuck. I managed to make a pointfree pipe but cant figure out composing.

// pointfree
const pipe = fn => future => future.pipe(fn)


// compose pipes   // not working
const composePipe = (...fns) => (...args) => fns.reduceRight(  (future, fn) => future.pipe(fn), args)[0];

Solution

  • I'll answer your question eventually, but let's take a step back first.

    An important thing to understand is that the pipe method is just function application. In other terms: future.pipe (f) == f (future).

    This means that your pipe function can be redefined as such:

    const pipe = fn => future => future.pipe(fn)
    //to:
    const pipe = fn => value => fn (value)
    

    This new version of pipe works exactly the same way, except that it works on any values, not just Futures. But let's take a step back further even.

    The signature of this function is as follows: pipe :: (a -> b) -> a -> b. It takes a function from A to B, and returns a function from A to B.

    Wait a minute....

    const pipe = fn => value => fn (value)
    //to:
    const pipe = fn => fn
    

    That new definition does the same thing. Except that it works on anything, not just Functions. Actually it's just the identity function. So a curried (you said point-free, but I think you meant curried) version of future.pipe is just the identity function.

    So why is this? Because all .pipe does is function application. And you can apply your functions yourself.


    Now to answer your next question about composing pipes. What you're actually looking for is something that takes a number of functions, and applies them in sequence.

    If you're using Ramda, that's pipe. We can implement this ourselves though:

    const pipe = (...fns) => (...args) => fns.reduce ((args, f) => [f (...args)], args)[0]