DEV Community

Discussion on: Ask me dumb questions about functional programming

Collapse
 
shepelevstas profile image
Shepelev Stas

Thanks! Good to know. But what about more general way, for example if I had a list of functions to try in order, like [getUserFromDb, getNewUser, trySmthElse, ....]? And I don't want to map that list into a list of results because that would mean execution of all of them, and I don't need a new user if getUserFromDB had found the one I needed.

Thread Thread
 
joelnet profile image
JavaScript Joel

Maybe something like this?

f = pipe([
  leftMap(getUserFromDb),
  leftMap(getNewUser),
  leftMap(trySmthElse)
])
Thread Thread
 
shepelevstas profile image
Shepelev Stas

Isn't leftMap, as a function (not a method .leftMap) takes an Either as its first argument? And to put up a pipe of leftMaps with Eithers I would need to first get all the Eithers and that would mean running all the functions again, which I try to avoid.

Thread Thread
 
shepelevstas profile image
Shepelev Stas • Edited

There is a function until in PureScript that is the closest to what I'm looking for: until :: ( a -> Boolean ) -> m a -> m a, but m is Monad, and I don't quite get yet how I can put a list of functions in it so that they will all get the same input value and be run one by one and tested after each run. until then returns a m a that is also can just be a list of results, kind of like map would produce, but that list will end as soon as (a -> Boolean) evaluates to true. Then I could just last on that m a result and, according to last definition, -> maybe get a successful output from the first succeeded function in the list =)

Thread Thread
 
shepelevstas profile image
Shepelev Stas

I think I found a somewhat simple solution!

const getUser = token => fold(
  (res, f) => res.isRight ? res : f(token),
  left('None Worked'),
  [getUserFromDB, getNewUser, someOtherAttempt, ...]
)
Thread Thread
 
joelnet profile image
JavaScript Joel

Ahh okay. I see what you are trying to do. Nice solution!