1

I am new to functional programming and I found the following fluture functional programming example that seems to give a really good example for handling database queries and subsequent data manipulation. The caveat however is that in reading about functional programming concepts, Just/Nothing monads seemed to be the suggested approach for handling null checking. 1) How would that fit into this example and 2) if the findOne rejected, would it stop the subsequent chains from running and immediately go to the fork?

import Future from 'fluture';

const processAll = Future.fork(_sendError, _sendResponse);

const _fetchFromDB =
    encaseP(userId => myModel.findOne({ id: userId }).exec())
  //Future.fromPromise(userId => myModel.findOne({ id: userId }).exec())

processAll(_fetchFromDB(userId)
  .chain(getDataGeneric)
  .chain(_findDevice)
  .chain(_processRequest))

I got this example from the following stackoverflow link and modified the fromPromise to encaseP:

How to make Either Monads be aware of of Async functions(Promises/Future)

I assume that encaseP would replace fromPromise in their example in converting a Promise to a Future.

user1790300
  • 2,143
  • 10
  • 54
  • 123

1 Answers1

1

Actually, Maybe (Nothing | Just) is often not what you want for handling errors because, although it can help you short-circuit subsequent operations and give you a hook to provide a default value, it won't tell you why the computation could not complete.

Either (Left | Right) gives you the same features but also lets you access the context that caused your flow to take the error branch because Left holds data too, like an error message, which is useful for recovering from errors, logging or displaying useful messages to the user.

Fluture gives you an async Either. Because it's async you can't retrieve the value directly (as you are used to with Promises) but apart from that it behaves the same as Maybe/Either: fork is the equivalent of fold. You will get short-circuiting and a lot more (like changing track, mapping over the reject branch, etc.).

There is a good introduction here https://dev.to/avaq/fluture-a-functional-alternative-to-promises-21b

geoffrey
  • 2,080
  • 9
  • 13
  • So, the Either gives you the ability to utilize await/async in the pipeline? – user1790300 Mar 07 '21 at 04:52
  • You can use the helper `promise` instead of `fork` if you want to run a Future computation as a Promise and be able to `await` it, but then you loose the ability to cancel it and exceptions will be mixed with the rejection branch, so it is best practice to use the many railway programming features of Fluture as much as possible and maybe run the computation as a Promise at the very edge of your program if you need to. You can't nest Promises and Futures anyway because Promises are eager while Futures are lazy: when you work with Fluture, everything you write is wishful thinking until you fork. – geoffrey Mar 07 '21 at 10:38