These are chat archives for ramda/ramda

20th
Jun 2018
lukasbash
@lukasbash
Jun 20 2018 11:05

Hey guys, quick question here: Is there a concept for stepping out of a pipe without throwing an error?
If it is not clear what I want to use here, I can roughly describe my use-case.

I have a wrapper function that does an access, lock and load operations on data from an external system. Into this function I pass a pipe of functions. Depending what happens inside the functions of the pipe, it should end earlier or later. (I know its already not good to code things like "function is aware of what happens inside", but because of my architecture its no possible in any other way.)

Pseudo code would be like (function wrapper not included) :
const myPipe = R.pipe(do, doMore, doFinal)
Each of the functions becomes the data from ext. system as param. If e.g. a condition in the function do matches, it should stop the pipe execution already.

Guess there is no concept/use-case for this right?

Tomas Lieberkind
@lieberkind
Jun 20 2018 11:35
Hi everyone 👋 Does anyone know what tool is used to generate the rambda docs page?
Brad Compton (he/him)
@Bradcomp
Jun 20 2018 15:31
@lieberkind I would take a look here: https://github.com/ramda/ramda.github.io
Ben Briggs
@ben-eb
Jun 20 2018 17:07
@lukasbash Sounds like a good use case for Maybe - where once you reach a Nothing the rest of the pipe isn't executed https://sanctuary.js.org/#maybe-type
Alternately if the value is required you should use Either https://sanctuary.js.org/#either-type
That way you can have a single pipe which will encapsulate the error handling without actually throwing
Brad Compton (he/him)
@Bradcomp
Jun 20 2018 17:20

Guess there is no concept/use-case for this right?

This is absolutely a common pattern in development.

I would agree that Either a b would probably be a good fit.

map will only operate if you have a Right(b), so returning a Left(a) will effectively short circuit any functions up until you either unwrap or explicity do something like mapLeft

I wouldn't suggest thinking of it only in terms of error handling though. Sometimes having a Left is a successful outcome, and having a Right means additional processing is needed.
If e.g. a condition in the function do matches, it should stop the pipe execution already.
const do = (stuff) => condition(stuff) ? Left('We are done') : Right(stuff);

pipe(
  do,
  map(doMore),
  map(doFinal)
)

//or soon
pipeWith(map, [do, doMore, doFinal]);
Ben Briggs
@ben-eb
Jun 20 2018 17:25
Something like this:
const R = require('ramda');
const S = require('sanctuary');

const myPipe = R.compose(
  S.either((e) => `Error: ${e}`)(R.identity),
  R.map(R.multiply(100)),
  S.toEither('No record found'),
  R.prop('id')
);

myPipe(null) // No record found
myPipe({ id: 1 }) // 100
@Bradcomp Yes that's a good way of looking at it too :)
Ben Briggs
@ben-eb
Jun 20 2018 17:30
Or indeed you could start with a Maybe :)
const myPipe = R.compose(
  S.either((e) => `Error: ${e}`)(R.identity),
  R.map(R.multiply(100)),
  S.maybeToEither('No record found'),
  S.get('id')
)
Ben Briggs
@ben-eb
Jun 20 2018 20:09
^ realised I forgot the predicate for S.get - should be S.get(S.I)('id') or S.get(R.identity)('id')
Though it's probably not in the spirit of sanctuary -- S.get(S.is($.Number)) probably better