These are chat archives for ramda/ramda

28th
Jul 2016
James Forbes
@JAForbes
Jul 28 2016 04:01
@dypsilon maybe R.compose(R.map(R.chain), Future.of)
zeecher Game
@zeecher
Jul 28 2016 10:01
How to remove repeating values from the list [1,2,3,4,5,3,4] to=> [1,2,3,4,5] ?
Found R.uniq
Aldwin Vlasblom
@Avaq
Jul 28 2016 10:09
There's also:
R.dropRepeats
Aldwin Vlasblom
@Avaq
Jul 28 2016 10:10
If you want to remove consecutive equal values.
Tim Navrotskyy
@dypsilon
Jul 28 2016 10:14
@JAForbes this looks very elegant, but I don't understand how it works. R.chain expects two arguments, the function and the value. What is the function in this case?
zeecher Game
@zeecher
Jul 28 2016 10:15
@Avaq R.dropRepeats didn't work for me on lists such as this -> [4,4,4,6,6,6,1,4,4,4,4] to get rid of repeats, it gave me [4,6,1,4] instead of [4,6,1]
hemanth.hm
@hemanth
Jul 28 2016 11:24
If you were to suggest a node module for https://nmotw.in/ what would it be?
Tim Navrotskyy
@dypsilon
Jul 28 2016 11:34
I was able to solve my aforementioned task with the allmighty reduce:
const reducer = (acc, cur) => {
    const [key, val] = cur;

    if (isFuture(val)) {
      return acc.chain((doc) => {
        return val.map((inner) => {
          return R.assoc(key, inner, doc);
        });
      });
    } else {
      return acc;
    }
  }

  return R.reduce(reducer, Future.of(doc), R.toPairs(doc));
Not sure if there is any simpler way...
The big problem I have here is that all computations are sequential now. I will try to solve this case using applicatives now.
Aldwin Vlasblom
@Avaq
Jul 28 2016 11:37
I believe this will cause every value on the object to be resolved in sequence (seeing as you use chain).
Ah, you are aware. :)
How deep do you need to resolve? One level?
Alright, I'll have a go at it.
Tim Navrotskyy
@dypsilon
Jul 28 2016 11:41
I hope one level and fear the day I will need more levels...
treating futures as values and passing them around is not as easy as I expected
Aldwin Vlasblom
@Avaq
Jul 28 2016 11:45
Nah, I usually map(assoc('k', __, o))(m) rather than plain assoc('k', __, o)(m). So to get a Future of the object, rather than an object of the Future.
Here's the first thing I came up with:
const resObj = R.pipe(
  R.toPairs,
  R.map(pair => Future.isFuture(pair[1])
              ? pair[1].map(_1 => [pair[0], _1])
              : Future.of(pair)),
  Future.parallel(Infinity),
  R.map(R.fromPairs)
)
resObj(doc) // Future Error Object
It runs in sequence.
Tim Navrotskyy
@dypsilon
Jul 28 2016 11:50
Do you mean in parallel?
Aldwin Vlasblom
@Avaq
Jul 28 2016 11:50
Ah, yes, whoops. Parallel! :D
Tim Navrotskyy
@dypsilon
Jul 28 2016 11:51
Great! This looks much simpler as derping around with applicatives...
Aldwin Vlasblom
@Avaq
Jul 28 2016 11:51
I'm using Future.parallel from Fluture here, but you might as well use R.sequence(Future.of) if you're not using Fluture.
Tim Navrotskyy
@dypsilon
Jul 28 2016 11:52
I do, Fluture is great
Aldwin Vlasblom
@Avaq
Jul 28 2016 11:53
So what we're doing here, is just mapping every Pair a (Future e b) to a Future e (Pair a b), and then resolving in parallel.
And every Pair a b is just wrapped in a Future.
You can make it look prettier if you environment supports destructuring.
Tim Navrotskyy
@dypsilon
Jul 28 2016 11:56
Yeah, it makes sense. Exactly what I need.
Mapping the whole pair to a Future is key.
Aldwin Vlasblom
@Avaq
Jul 28 2016 11:58
If you want this to work on deeper levels, I guess you would have to make some kind of toPaths and fromPaths utilities to use in place of toPairs and fromPairs. But the rest of the code wouldn't have to change.
Tim Navrotskyy
@dypsilon
Jul 28 2016 11:59
What would toPaths and fromPaths do? I suppose convert a nested array to a flat one?
Aldwin Vlasblom
@Avaq
Jul 28 2016 12:00
I guess something like:
//toPaths :: Object a -> Array (Pair Path a)

toPaths({foo: {bar: 'baz'}, nyerk: 'snarl'})
> [[['foo', 'bar'], 'baz'], [['nyerk'], 'snarl']]
So instead of a Key inside Pair, we get a Path.
Tim Navrotskyy
@dypsilon
Jul 28 2016 12:01
Oh, I see
That should work, I'll make a note for later...
@Avaq thank you fo the help!
zeecher Game
@zeecher
Jul 28 2016 12:08
This message was deleted
Aldwin Vlasblom
@Avaq
Jul 28 2016 12:09
@dypsilon Oh, I think alternatively you might try to make it recursive, something like:
//...
pair => Future.isFuture(pair[1])
              ? pair[1].chain(_1 => isObject(_1) ? resObj(_1).map(__1 => [pair[0], __1]) : Future.of([pair[0], _1]))
              : Future.of(pair))
//...
But I did kinda like the elegance of the toPaths solution. Not sure which is better/faster/stronger.
zeecher Game
@zeecher
Jul 28 2016 12:11
// How to convert this list:
[
{
    fruit : Banana
    name : John

},
{
    fruit : Apple
    name: Alex
},
{
    fruit : Apple
    name: Nancy
},
{
    fruit : Banana
    name: Lily
},
]

// to following list [

{
    fruit : banana,
    people : [{name: John, name: Lily}]    
}

{
    fruit : Apple,
    people : [{name: Alex, name: Nancy}]    
}
]

// thanks...
Tim Navrotskyy
@dypsilon
Jul 28 2016 12:13
@Avaq toPaths looks simpler, in my opinion
Jigar Gosar
@jigargosar
Jul 28 2016 13:08
This message was deleted
//Ramda
_.ifElse(
        _.compose(_.equals(num), _.last),
        _.compose(_.call(_.__, [num * 2, 0]), _.concat, _.init),
        _.append(num)
);

// pseudo functional
if (_.last(list) === num) {
    return _.concat(_.init(list), [num * 2, 0])
} else {
    return _.append(num, list);
}
Am I using ramda functions incorrectly? can the functional code be made more expressive? or should I stick to pseudo functional style in this case since there aren't better functional alternative? Please share your thoughts. @CrossEye Would really appreciate your input. and your take on such scenarios.
Denis Stoyanov
@xgrommx
Jul 28 2016 14:36
@ram-bot
var list = [
{
    fruit : 'Banana',
    name : 'John'

},
{
    fruit : 'Apple',
    name: 'Alex'
},
{
    fruit : 'Apple',
    name: 'Nancy'
},
{
    fruit : 'Banana',
    name: 'Lily'
},
]

compose(map(v => ({
  fruit: prop('fruit')(head(v)),
  people: map(omit('fruit'))(v)
})), values, groupBy(prop('fruit')))(list)
ram-bot
@ram-bot
Jul 28 2016 14:36
[ { fruit: 'Banana',
    people: [ { name: 'John' }, { name: 'Lily' } ] },
  { fruit: 'Apple',
    people: [ { name: 'Alex' }, { name: 'Nancy' } ] } ]
Denis Stoyanov
@xgrommx
Jul 28 2016 14:36
@zeecher
var list = [
{
    fruit : 'Banana',
    name : 'John'

},
{
    fruit : 'Apple',
    name: 'Alex'
},
{
    fruit : 'Apple',
    name: 'Nancy'
},
{
    fruit : 'Banana',
    name: 'Lily'
},
]

compose(map(v => ({
  fruit: prop('fruit')(head(v)),
  people: map(omit('fruit'))(v)
})), values, groupBy(prop('fruit')))(list)
Denis Stoyanov
@xgrommx
Jul 28 2016 14:51
@zeecher point-free
compose(
  map(converge(merge, [compose(omit('name'), head), compose(objOf('people'), map(omit('fruit')))])), 
  values, 
  groupBy(prop('fruit'))
)(list)
Aaron Mc Adam
@aaronmcadam
Jul 28 2016 16:51
Does anybody have any improvement ideas on this little snippet?
    return fetchImages(projectId, taskId).then(
      R.compose(
        R.prop('task'),
        images => R.assocPath(['task', 'images'], images, task)
      )
    );
Aaron Mc Adam
@aaronmcadam
Jul 28 2016 17:07
I ended up with:
const setImages = R.curry((task, images) => (
  R.compose(
    R.prop('task'),
    R.assocPath(['task', 'images'])
  )(images, task)
));
Aldwin Vlasblom
@Avaq
Jul 28 2016 17:12
const setImages = R.flip(R.compose(
  R.prop('task'),
  R.assocPath(['task', 'images'])
));
..maybe?
Aaron Mc Adam
@aaronmcadam
Jul 28 2016 17:24
ah I tried flip, but on the assocPath call itself, but that worked, thanks @Avaq!