These are chat archives for ramda/ramda

20th
Mar 2019
Nika
@overflowz
Mar 20 00:23

OK another question. I'm new into FP and I love it already! Honestly, ramda and ramda-fantasy played big role, I won't lie ;p My question is, what's the difference between IO and Reader monads? What I see so far they do almost the same thing, e.g.

const R = require('ramda');
const RF = require('ramda-fantasy');

const logWithReader = name => RF.Reader(env => {
  env.log(name);
});

const logWithIO = name => RF.IO(env => {
  env.log(name);
});

logWithReader('hello')
  .run({ log: console.log });

logWithIO('world')
  .runIO({ log: console.log });

But what's the catch?

Ben Briggs
@ben-eb
Mar 20 10:11
@overflowz I'm not sure there is a distinction between them that can be enforced in JS, it's more of a haskell thing
Nika
@overflowz
Mar 20 10:28
I have hard time understanding haskell code but I'll try. thanks!
Ben Briggs
@ben-eb
Mar 20 13:13
Yeah, me too. :) No worries!
Daniele Dellafiore
@ildella
Mar 20 18:05

Hi everybody. I'm relatively new to Ramda and today I am trying to use pipeWith in place of the deprecated pipeP as I need to have something like this working with promises:

const pipeWhileNotNil = R.pipeWith((f, res) => R.isNil(res) ? res : f(res))
pipeWhileNotNil([f1, f2])

This is a classic pipe that fails if one function returns nil, and f1/f2 are standard functions
how can I make this work if f1/f2 are promises?

In 0.26 release I see pipeP has become pipeWith(then) but my understanding of the whole things ends there :/
Thanks for any help in advance!

Brad Compton (he/him)
@Bradcomp
Mar 20 18:09

how can I make this work if f1/f2 are promises?

Do you mean if they are Promises that contain functions, or Functions that return Promises?

Daniele Dellafiore
@ildella
Mar 20 18:16
functions that return promises
const f1 = async param => param + 1
Brad Compton (he/him)
@Bradcomp
Mar 20 18:19

@ram-bot ```js
const f1 = x => Promise.resolve(x + 1);
const f2 = x => Promise.resolve(x * 2);

pipeWith(then)([f1, f2])(11); // Promise(24)
```

hmmm
If it helps we can break down the example
Daniele Dellafiore
@ildella
Mar 20 18:36
I'll try that thanks!
Daniele Dellafiore
@ildella
Mar 20 22:24
ummmm.. not sure I get it
so what should be 'then', something like const then = (f, res) => R.isNil(res) ? res : f(res)
Brad Compton (he/him)
@Bradcomp
Mar 20 22:25
then is just for promises
Do you want to be able to handle null checks inside promises
Daniele Dellafiore
@ildella
Mar 20 22:26
what I do not understand is how a 'then' should be implemented, this does not help me: https://ramdajs.com/docs/#then
I want to implement the same logic expressed in my original example:
const pipeWhileNotNil = R.pipeWith((f, res) => R.isNil(res) ? res : f(res))
but with promises so I Can apply that to async functions that calls DBs, APIs...
and I can't understand the 'then'
Brad Compton (he/him)
@Bradcomp
Mar 20 22:29

Alright, let's start there...

Here is then in its simplest form:

const then = (func, promise) => promise.then(func);
So then when we plug that into pipeWith and change the variable names:
const pipeP = pipeWith((f, res) => res.then(f));
Now we can see the similarity with your example, but we need to modify it to handle the null case as well
Daniele Dellafiore
@ildella
Mar 20 22:31
ok the simplest form helps... I'll try with that thanks
ok this is where I needed to get, this pass:
const then = (func, promise) => promise.then(func)
const f1 = x => Promise.resolve(x + 1)
const f2 = x => Promise.resolve(x * 2)

const result = await R.pipeWith(then)([f1, f2])(11)
expect(result).toBe(24)
with this, I can then make the "then" logic I want and so on...
Brad Compton (he/him)
@Bradcomp
Mar 20 22:34
yes!
Daniele Dellafiore
@ildella
Mar 20 22:35
let's see if I can apply a conditional on the promise response as I was doing with the previous example
the whole point of this is to have a pipe of funcions that are executed on cascade, each output is the next function input, they are "async" and if one fails, then the pipe stops