fluture-js / Fluture

🦋 Fantasy Land compliant (monadic) alternative to Promises
MIT License
2.48k stars 84 forks source link

Railway Oriented Programming with Fluture #397

Closed mohsensaremi closed 4 years ago

mohsensaremi commented 5 years ago

Railway Oriented Programming(ROP) is explained here: https://fsharpforfunandprofit.com/rop/

Is there any way to use this pattern with Fluture

I can do ROP with these two helper methods like this:

const bind = f => x => Future.attempt(() => f(x));
const bindAsync = f => x => Future.tryP(() => f(x));

Future.of("TEST")
    .chain(bind(doThis))
    .chain(bind(doThat))
    .chain(bindAsync(doThisAsync))
    .chain(bindAsync(doThatAsync))
    .chain(bind(doAnotherThing))
    .chain(bindAsync(doAnotherThingAsync))
    .
    .
    .

Is there a better way to remove bind, bindAsync and do binding automatically?

Avaq commented 5 years ago

Fluture is inherently a "railway oriented programming" library. You don't need your own implementation of bind, because chain is monadic bind.

Note also that your bind is just Future.encase, and your bindAsync is actually just Future.encaseP. So you could have written:

const bind = Future.encase
const bindAsync = Future.encaseP

Furthermore, chain (encase (f)) is equivalent to map (f) (assuming f doesn't throw). So in that case, your code can be changed altogether into the following:

Future.of("TEST")
.map(doThis)
.map(doThat)
.chain(encaseP(doThisAsync))
.chain(encaseP(doThatAsync))
.map(doAnotherThing)
.chain(encaseP(doAnotherThingAsync))
Avaq commented 5 years ago

By the way, you are welcome to join our Gitter chat room for small questions like this - usually you can get a faster answer there. There's also a stack overflow tag under which you can ask Fluture-related questions.

Avaq commented 4 years ago

Closing this as I don't see further action to be taken.