These are chat archives for ramda/ramda

13th
Jul 2016
Emilio Srougo
@Emilios1995
Jul 13 2016 01:01
Is there any way to pick nested props? for example:
const user = { id: 1, createdAt: 0023452  profile: { name: 'foo' ,  lastName: 'bar' }  }
const result = { id: 1, name: 'foo', lastName: 'bar' }  // I want to pick id, name and lastName
@JAForbes That's a useful table
Denis Stoyanov
@xgrommx
Jul 13 2016 01:20
Denis Stoyanov
@xgrommx
Jul 13 2016 01:35
@ram-bot
const o = { id: 1, createdAt: '0023452',  profile: { name: 'foo' ,  lastName: 'bar' }  };

lift(merge)(pick(['id']), prop('profile'))(o);
ram-bot
@ram-bot
Jul 13 2016 01:35
{ id: 1, name: 'foo', lastName: 'bar' }
Emilio Srougo
@Emilios1995
Jul 13 2016 02:45
@xgrommx Interesting. I'm know the concept of lifting, but don't understand why it works here.
Emilio Srougo
@Emilios1995
Jul 13 2016 03:01
Could someone please provide some explanation?
Jethro Larson
@jethrolarson
Jul 13 2016 03:13
Well
lift(merge) gives you a function that takes two applicatives and returns their union
pick(['id']) is a function not an applicative, so I'm lost
Brad Compton (he/him)
@Bradcomp
Jul 13 2016 03:17
I think functions are an instance of applicative
Jethro Larson
@jethrolarson
Jul 13 2016 03:17
I just read the docs and yeah, you can put a function there
Brad Compton (he/him)
@Bradcomp
Jul 13 2016 03:18
@ram-bot
const o = { id: 1, createdAt: '0023452',  profile: { name: 'foo' ,  lastName: 'bar' }  };

converge(merge, [pick(['id']), prop('profile')])(o);
ram-bot
@ram-bot
Jul 13 2016 03:18
{ id: 1, name: 'foo', lastName: 'bar' }
Brad Compton (he/him)
@Bradcomp
Jul 13 2016 03:19
converge is, in essence, sugar over a special case of lift
Jethro Larson
@jethrolarson
Jul 13 2016 03:19
That's a little less bewildering
I'm still kind of confused about how lift(binary)(unary, unary) gives a unary function
Emilio Srougo
@Emilios1995
Jul 13 2016 03:30
@Bradcomp yes, this is the ideal use case of converge.
But I second @jethrolarson , I still don't understand this usage of lift
Jethro Larson
@jethrolarson
Jul 13 2016 03:32
liftA2 = f => (a, b) => a.of(f).ap(a).ap(b)
Brad Compton (he/him)
@Bradcomp
Jul 13 2016 03:34
R.ap
Emilio Srougo
@Emilios1995
Jul 13 2016 03:34
Or liftA2 = f => (a, b) => a.map(f).ap(b)
Brad Compton (he/him)
@Bradcomp
Jul 13 2016 03:34
ap applies a list of functions to a list of values.
Jethro Larson
@jethrolarson
Jul 13 2016 03:35
lifting a function into a function that works on functions
@_@
Maybe this has something to with map(f, g) being the same as compose(f, g), right?
Brad Compton (he/him)
@Bradcomp
Jul 13 2016 03:39
So I'm not 100% on this stuff, but it's definitely related.
Jethro Larson
@jethrolarson
Jul 13 2016 03:41
pick(['a']) .map(merge) .ap(prop('b'))
obv something needs to supply the applicative and functor implementation for function since it's not part of js
but if f.map(g) is f • g then compose(pick(['a'], merge)
I must have that backwards.
Jethro Larson
@jethrolarson
Jul 13 2016 03:50
Yeah, I give up.
Maybe if I saw the applicative impl of function
Scott Christopher
@scott-christopher
Jul 13 2016 04:00
@jethrolarson
Function.prototype.ap = function(g) {
  return x => this(x)(g(x))
}
Chet Harrison
@ChetHarrison
Jul 13 2016 04:00
yo @scott-christopher whats your take on the def of an "applicative"?
is it "of" or "apply" or both
Scott Christopher
@scott-christopher
Jul 13 2016 04:01
An applicative typically is defined by both apply and of.
so a way to apply a function within the context of a functor and a way to produce a pure value in the context of a functor
Emilio Srougo
@Emilios1995
Jul 13 2016 04:03
It conceptually makes sense because a curried function is an applicative, because it contains a function.
Chet Harrison
@ChetHarrison
Jul 13 2016 04:03
k that was what I was getting the sense of but the FL spec put "of" in the "applicative" def and "ap" in the "apply" def so was tad confused
Emilio Srougo
@Emilios1995
Jul 13 2016 04:03
But where is that implementation defined @scott-christopher ?
Scott Christopher
@scott-christopher
Jul 13 2016 04:05
@Emilios1995 One place you'll find it is in the implementation of the Reader type
Emilio Srougo
@Emilios1995
Jul 13 2016 04:08
Yes, but where is it defined in a JS/Ramda enviroment?
Scott Christopher
@scott-christopher
Jul 13 2016 04:08
The snippet I pasted above wasn't taken from anywhere in particular.
You can see the Ramda Fantasy version of Reader's ap here: https://github.com/ramda/ramda-fantasy/blob/master/src/Reader.js#L24-L28
Ramda's default implementation is here: https://github.com/ramda/ramda/blob/master/src/ap.js#L30-L31
You might also recognise it as the S combinator
(S x y z) = (x z (y z))
Emilio Srougo
@Emilios1995
Jul 13 2016 04:21

Oh, I see. However...

I'm still kind of confused about how lift(binary)(unary, unary) gives a unary function

Scott Christopher
@scott-christopher
Jul 13 2016 04:31
Perhaps it might help to see some translations of the same thing?
@ram-bot
lift(add)(prop('foo'), prop('bar'))({ foo: 1, bar: 2 })
ram-bot
@ram-bot
Jul 13 2016 04:31
3
Jethro Larson
@jethrolarson
Jul 13 2016 04:31
@Emilios1995 Now that I see an example impl of Function.prototype.apthat @scott-christopher provided it's much clearer
Scott Christopher
@scott-christopher
Jul 13 2016 04:31
@ram-bot
ap(map(add, prop('foo')), prop('bar'))({ foo: 1, bar: 2 })
ram-bot
@ram-bot
Jul 13 2016 04:31
3
Scott Christopher
@scott-christopher
Jul 13 2016 04:31
@ram-bot
ap(compose(add, prop('foo')), prop('bar'))({ foo: 1, bar: 2 })
ram-bot
@ram-bot
Jul 13 2016 04:31
3
Jethro Larson
@jethrolarson
Jul 13 2016 04:33
the real meat is understanding what an ap does when the category is function
Yeah, I did recognize S. I always wondered what it was good for :)
Jethro Larson
@jethrolarson
Jul 13 2016 04:39
Function.prototype.ap = function(g) {
  return S(this, g);
}
If S is curried :)
Emilio Srougo
@Emilios1995
Jul 13 2016 04:58
Oh, thank you @scott-christopher! It's all clear now. It was confusing because I had only seen ap on maybes and stuff.
Denis Stoyanov
@xgrommx
Jul 13 2016 06:36
:smile:
If we have lift, converge is unnecessary. Anyway we can use only applicative functor (but lift is a composition of applicative functors)
Tushar Mathur
@tusharmath
Jul 13 2016 11:13
How can I use R.addIndex with R.scan ?
James Forbes
@JAForbes
Jul 13 2016 11:34
oh wow, I didn't even know Ramda had R.scan
@tusharmath not sure sorry, I just tried it out a bit and couldn't figure out.
Tushar Mathur
@tusharmath
Jul 13 2016 11:39
@JAForbes I got it to work with — R.addIndex(R.scan) :)
James Forbes
@JAForbes
Jul 13 2016 12:03
I tried that and couldn't get it to work - weird
Happy it worked for you :)
hkrutzer
@hkrutzer
Jul 13 2016 13:15
how would I take several lists with items, each list of a different shape, but each with an ID field, and group the items with the same IDs together?
Barney Carroll
@barneycarroll
Jul 13 2016 13:16
Can you show what 2 of these lists might look like @hkrutzer ?
hkrutzer
@hkrutzer
Jul 13 2016 13:17
yes, a: [{itemID: 1, foo: 4, bar: 'x'}, {itemID: 2, foo: 4, bar: 'x'}]
b: [{itemID: 1, baz: 10000}, {itemID: 2, baz: 40000}]
Barney Carroll
@barneycarroll
Jul 13 2016 13:18
When you say "each list of a different shape", you mean "each item", right?
hkrutzer
@hkrutzer
Jul 13 2016 13:19
no, each item in a single list has the same fields
Barney Carroll
@barneycarroll
Jul 13 2016 13:20
What's the shape of a list?
I think you're after groupWith
hkrutzer
@hkrutzer
Jul 13 2016 13:21
groupWith takes a single list
I mean the fields it has
Barney Carroll
@barneycarroll
Jul 13 2016 13:21
Oh, I see
So for that example, you would want to receive
[{itemID: 1, foo: 4, bar: 'x', baz: 10000}, {itemID: 2, foo: 4, bar: 'x' baz:40000}]
?
hkrutzer
@hkrutzer
Jul 13 2016 13:27
[{itemID: 1, [{foo: 4, bar: 'x'}, {baz: 10000}] }, ]
there are overlapping field names and I want to preserve all values
think I'll just have to reduce
Brad Compton (he/him)
@Bradcomp
Jul 13 2016 13:40
@hkrutzer can you concatenate
the two lists then call groupWith?
Or... groupBy
@ram-bot
var a = [{itemID: 1, foo: 4, bar: 'x'}, {itemID: 2, foo: 4, bar: 'x'}]
var b = [{itemID: 1, baz: 10000}, {itemID: 2, baz: 40000}]

compose(groupBy(prop('itemID')), concat)(a, b)
ram-bot
@ram-bot
Jul 13 2016 13:43
[{"bar": "x", "foo": 4, "itemID": 1}, {"bar": "x", "foo": 4, "itemID": 2}] does not have a method named "concat"
Brad Compton (he/him)
@Bradcomp
Jul 13 2016 13:44
Oh yeah, concat doesn't work for ram-bot
hkrutzer
@hkrutzer
Jul 13 2016 13:56
cool, thanks :)
Emilio Srougo
@Emilios1995
Jul 13 2016 14:18
Where does Maybe come from in the Ramda Repl?
Brad Compton (he/him)
@Bradcomp
Jul 13 2016 14:29
@Emilios1995 Ramda-Fantasy
You can also use S.Maybe if you want
Drew
@dtipson
Jul 13 2016 15:01
I thought maybe native Promises could be made to play nice with things like R.sequence, but maybe not: http://goo.gl/g3QrEW ?
tl:dr version is that sequence(Promise.of, [rejectAfter(9), rejectAfter(30)]) will pass on the last listed rejection error, whereas Promise.all and sequence+Futures will pass through the first (timewise) rejection error. The latter being the preferable behavior
It might be something wrong with my implementation, but it also could be because of that dang overloaded .then
Drew
@dtipson
Jul 13 2016 15:06
I've been trying to work out what a standalone Array.prototype.sequence would look like and seeing the same problem when used on Promises (rejection by order instead of by time) in place of Promise.all
Drew
@dtipson
Jul 13 2016 15:29
Here's one also with a custom Array.sequence that shows the same defect with Promises: http://goo.gl/87VNZs
Drew
@dtipson
Jul 13 2016 18:05
Got set straight: https://twitter.com/drboolean/status/753272002220220417 any Promise.ap meant to work with ops like sequence has to be parallelized, just like Task's ap did (and is now): http://goo.gl/r2o7es
Tim Navrotskyy
@dypsilon
Jul 13 2016 20:14
Hi, everyone, is there a recursive merge function?
Tim Navrotskyy
@dypsilon
Jul 13 2016 20:24
ok, found the deepMerge issue on github, seems like its WIP