These are chat archives for ramda/ramda

2nd
Aug 2016
Lawrence Pan
@lpan
Aug 02 2016 00:11
hey it seems that R.concat does not work on node.js does anyone have a fix? thanks :) I am on node.js 6.3.1 and ramda 0.21.0
Brad Compton (he/him)
@Bradcomp
Aug 02 2016 00:18
@lpan Can you give an example? What do you mean by not work?
Brad Compton (he/him)
@Bradcomp
Aug 02 2016 01:14
nevermind. Just upgraded to 6.3.1 from 6.0.0 and got the error
Lawrence Pan
@lpan
Aug 02 2016 01:24
@Bradcomp I had to downgrade it to 0.17.0 :'( apparently there is already a fix in the current master. Does ramda do patch release?
Brad Compton (he/him)
@Bradcomp
Aug 02 2016 01:33
Dunno
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 11:33
How would we set a default argument when using point-free? That doesn’t make sense, does it?
James Forbes
@JAForbes
Aug 02 2016 11:34
You can use something like R.propOr or R.either, or even R.or depending on the situation
James Forbes
@JAForbes
Aug 02 2016 11:45
R.merge could be used as well
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 12:03
const fetchAttributes = (taskId, segmentId = 'All') => (
  R.composeP(
    mapAttributes,
    callBizApi
  )(getEndpoints(taskId, segmentId))
);
Can composeP take regular functions that aren’t thenable? To kick off the pipeline?
@JAForbes There’s the function in question above
James Forbes
@JAForbes
Aug 02 2016 12:06
@aaronmcadam Try swapping the argument order. And then currying it.
Its not exactly the same, but you get access to to all possible branches, and you can prefill the segmentId
Risto Novik
@riston
Aug 02 2016 14:24
Hello, is there more effective way to remove the object first key, its dynamic { a: { b: 1, c: 3 } } -> { b: 1, c: 3 }, one way is to get all the keys and then access with it?
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 14:25
@ram-bot R.dissoc(‘a’, { a: { b: 1, c: 3 } })
Risto Novik
@riston
Aug 02 2016 14:26
R.head(R.values({ a: { b: 1, c: 3 } }))
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 14:26
I don’t know how to rambot lol
James Forbes
@JAForbes
Aug 02 2016 14:26
R.converge(
  R.dissoc
  ,[
     R.pipe(
       R.keys
       ,R.head
     )
     ,R.identity
  ]
)
I know this can be done with ap somehow, but I still haven't cracked that nut
Risto Novik
@riston
Aug 02 2016 14:26
yea but the key 'a' isn't fixed
Aldwin Vlasblom
@Avaq
Aug 02 2016 14:27
@aaronmcadam I think you used the wrong quotation marks: vs '.
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 14:27
ah it converted it :)
Thanks @Avaq
OSX substitutions are so useless for us engineers
Aldwin Vlasblom
@Avaq
Aug 02 2016 14:31

substitutions are

Did you mean "is"?

Aaron Mc Adam
@aaronmcadam
Aug 02 2016 14:32
No, I didn't
Aldwin Vlasblom
@Avaq
Aug 02 2016 14:32
Joking
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 14:32
I see now lol
I've got a bit of an annoying issue - a nested promise
Can anybody have a quick look to see if there's a nicer way to deal with them?
Risto Novik
@riston
Aug 02 2016 14:36
the catch is needed ? .catch(error => Promise.reject(error));
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 14:37
I need it so it will bubble up to my route definition
Risto Novik
@riston
Aug 02 2016 14:37
just offtopic >D
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 14:37
It doesn't seem to work
yeah, I know, sorry :)
I've added the route file to the gist
Aldwin Vlasblom
@Avaq
Aug 02 2016 14:41
@aaronmcadam The getRelationEndpoints has to be nested because you need to enclose over response. You could do something like return callBizApi(...).then(x => [x, response]) and then unnest the subsequent call to then(). But really, this is the exact use-case where coroutines shine, so if you can use them, I'd say go for it.
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 14:42
Do you mind explaining what you mean by coroutines @Avaq ?
James Forbes
@JAForbes
Aug 02 2016 14:43
@riston @ram-bot
const removeFirstKey = chain( 
  R.pipe(R.keys,R.head)
 ,R.dissoc
)

removeFirstKey({ a:1, b:2, c:3})
Ah I have no idea how to get rambot to work, but I finally got chain to work with a function. That has been killing me for at least a month
Aldwin Vlasblom
@Avaq
Aug 02 2016 14:49
@aaronmcadam ES6 Generator-based flow control: https://github.com/tj/co
Risto Novik
@riston
Aug 02 2016 14:53
@JAForbes thats good one, but the key "a" is nested
James Forbes
@JAForbes
Aug 02 2016 14:56
Oh I misunderstood what you meant by remove the first key @riston
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 14:57
Really dumb one here, but should I convert this (const getEndpoints = projectId => [/projects/${projectId}/segments];) to use R.replace and put a slug I can replace, like :projectId
James Forbes
@JAForbes
Aug 02 2016 14:59
Your existing code is better I think.
Denis Stoyanov
@xgrommx
Aug 02 2016 15:00
:smile:
James Forbes
@JAForbes
Aug 02 2016 15:00
Alright I can get chain to work, but stuck on ap
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 15:00
yay point-ful wins :D
Denis Stoyanov
@xgrommx
Aug 02 2016 15:01
@JAForbes chain is a >>= and chain(x => [x, x * 10, x * 20])([1,2,3])
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 15:04
Any improvements over this?
export const mapSegments = R.compose(
  R.map(R.compose(idToString, getSegment)),
  R.prop('segments')
);
Does evolve work over a list?
Denis Stoyanov
@xgrommx
Aug 02 2016 15:05
@aaronmcadam what is a problem? looks like good
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 15:06
Yeah, I like it too, I was just asking if there was a slightly better way of composing it :)
There's still lots of Ramda I've got to learn
Denis Stoyanov
@xgrommx
Aug 02 2016 15:06
evolve({segments: map(compose(idToString, getSeegment))} maybe this one
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 15:07
I was thinking, I could use do something like that and then read the prop off at the end of the pipeline
I guess it doesn't make a lot of difference here
I guess there's not a lot of point creating a new object only to read its prop off at the end
Thanks @xgrommx :)
James Forbes
@JAForbes
Aug 02 2016 15:14

@scott-christopher just trying to follow those axioms you posted a few days ago about ap/chain being able to behave like converge

Chain works great, but I can't get ap to work

http://ramdajs.com/repl/#?code=%2F%2A%0A%2F%2F%20f%20%3A%3A%20a%20-%3E%20b%20-%3E%20c%0A%2F%2F%20g%20%3A%3A%20a%20-%3E%20b%0Aap%28f%2C%20g%29%20%3D%20converge%28f%2C%20%5Bidentity%2C%20g%5D%29%0A%2F%2F%20f%20%3A%3A%20b%20-%3E%20a%20-%3E%20c%0A%2F%2F%20g%20%3A%3A%20a%20-%3E%20b%0Achain%28g%2C%20f%29%20%3D%20converge%28f%2C%20%5Bg%2C%20identity%5D%29%3B%0A%2A%2F%0A%0Aconst%20firstKey%20%3D%20R.pipe%28R.keys%2CR.head%29%0A%0A%2F%2F%20chain%28g%2C%20f%29%20%3D%20converge%28f%2C%20%5Bg%2C%20identity%5D%29%3B%0Aconst%20removeFirstKeyChain%20%3D%20%0A%20%20chain%28%20%0A%20%20%20%20firstKey%0A%20%20%20%2CR.dissoc%0A%20%20%29%0A%0A%0A%2F%2F%20ap%28f%2C%20g%29%20%3D%20converge%28f%2C%20%5Bidentity%2C%20g%5D%29%0Aconst%20removeFirstKeyAp%20%3D%20%0A%20%20ap%28%0A%20%20%20%20R.flip%28R.dissoc%29%0A%20%20%20%20%2CfirstKey%0A%20%20%29%0A%0A%0A%2F%2F%20chain%28g%2C%20f%29%20%3D%20converge%28f%2C%20%5Bg%2C%20identity%5D%29%3B%0Aconst%20removeFirstKeyConverge%20%3D%20%0A%20%20converge%28%0A%20%20%20%20dissoc%0A%20%20%20%20%2C%5B%0A%20%20%20%20%20%20firstKey%0A%20%20%20%20%20%20%2Cidentity%0A%20%20%20%20%5D%0A%20%20%29%0A%0A%2F%2F%20ap%28f%2C%20g%29%20%3D%20converge%28f%2C%20%5Bidentity%2C%20g%5D%29%0Aconst%20removeFirstKeyConvergeFlipped%20%3D%20%0A%20%20converge%28%0A%20%20%20%20flip%28dissoc%29%0A%20%20%20%20%2C%5B%0A%20%20%20%20%20%20identity%0A%20%20%20%20%20%20%2CfirstKey%0A%20%20%20%20%5D%0A%20%20%29%0A%0A%0Aconst%20main%20%3D%20%0A%20%20R.pipe%28%0A%20%20%20%20R.ap%28%5B%0A%20%20%20%20%20%20removeFirstKeyConverge%0A%20%20%20%20%20%20%2CremoveFirstKeyAp%0A%20%20%20%20%20%20%2CremoveFirstKeyChain%0A%20%20%20%20%20%20%2CremoveFirstKeyConvergeFlipped%0A%20%20%20%20%5D%29%0A%20%20%20%20%2CR.map%28R.equals%28%7B%20b%3A2%2C%20c%3A3%20%7D%29%29%0A%20%20%20%20%2CR.zipObj%28%5B%0A%20%20%20%20%20%20%27removeFirstKeyConverge%27%0A%20%20%20%20%20%20%2C%27removeFirstKeyAp%27%0A%20%20%20%20%20%20%2C%27removeFirstKeyChain%27%0A%20%20%20%20%20%20%2C%27removeFirstKeyConvergeFlipped%27%0A%20%20%20%20%5D%29%0A%20%20%29%0A%0Amain%28%5B%7B%20a%3A1%2C%20b%3A2%2C%20c%3A3%20%7D%5D%29

Aaron Mc Adam
@aaronmcadam
Aug 02 2016 15:14
Ok, one more, I think I can use evolve to set the first two keys here, id and completedAt, but how would I set the participantName? I know I could use path, but how could I make it so I have an object with just the 3 keys?. Here's the function:
export const mapResponses = R.compose(
  R.map(response => ({
    id: response.id.toString(),
    completedAt: formatDate(response.completedAt),
    participantName: response.participant.name
  })),
  R.prop('responses')
);
James Forbes
@JAForbes
Aug 02 2016 15:16
are all the field's strings @aaronmcadam ?
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 15:16
const formatResponse = R.evolve({
  id: R.toString,
  completedAt: formatDate
})
The first 2 values are strings, the 3rd reads a participant object
James Forbes
@JAForbes
Aug 02 2016 15:17
and the name is a string?
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 15:17
ya
ohh I can use a sub object
ah, but I don't want to format that, damn
James Forbes
@JAForbes
Aug 02 2016 15:19
does particpantName have to be called participantName?
or can it be called participant?
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 15:19
yeah, it's part of the defined schema
James Forbes
@JAForbes
Aug 02 2016 15:19
despite being a name
ok
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 15:19
the front end depends on it, it'd be a bit too much work to update it everywhere
Brad Compton (he/him)
@Bradcomp
Aug 02 2016 15:20
@ram-bot
R.concat([1], [2])
ram-bot
@ram-bot
Aug 02 2016 15:20
[1] does not have a method named "concat"
James Forbes
@JAForbes
Aug 02 2016 15:20
R.pipe(
  R.pick(['id', 'completedAt', 'participant'])
  ,R.values
  ,R.zipObj(['id', 'completedAt', 'participantName'])
  ,R.evolve({ participantName: R.prop('name'), completedAt: formatDate })
  ,R.map(String)
)
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 15:22
hmm, thanks!
James Forbes
@JAForbes
Aug 02 2016 15:22
forgot formatDate ^^
@aaronmcadam :thumbsup:
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 15:29
I cry a little bit when the point-free version isn't nicer than the imperative :D
James Forbes
@JAForbes
Aug 02 2016 15:29
Well... maybe it isn't as concise, but there is something to be said for making all the transforms unidirectional
at least I think so
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 15:29
I understand what you mean
and I think FP thrives on making everythings lists and then zipping
But I think we need to balance the complexity a little bit. This is just a factory function after all :)
James Forbes
@JAForbes
Aug 02 2016 15:30
and we can design our data structures to make transforms easier as well
some structures are hard to transform, but there isn't much of a justification for the structure to be that way
often
not always
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 15:33
Yeah, I know what you mean. It's just the whole point of these endpoints I'm writing is to simplify the data structures returned by another API :)
James Forbes
@JAForbes
Aug 02 2016 15:33
yeah which is always fun
but yeah your original code is probably better
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 15:38
I really like the tersness of evolve though, grr
Denis Stoyanov
@xgrommx
Aug 02 2016 15:38
@aaronmcadam so, I don't understand your case now
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 15:38
I think it goes a great job of declaring the transforms
What do you mean @xgrommx ?
Denis Stoyanov
@xgrommx
Aug 02 2016 15:39
@aaronmcadam about evolve =)
James Forbes
@JAForbes
Aug 02 2016 15:39
@aaronmcadam evolve is great yeah
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 15:40
I'm still not following :
James Forbes
@JAForbes
Aug 02 2016 15:40
@xgrommx I think @aaronmcadam is saying evolve is great, but he is ultimately going to pick the original non point free version
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 15:40
Sorry, @xgrommx can you explain?
I've just tried using merge to see if that would be a bit easier to read
so, evolve-ing the data transforms then then merging in the path
But then I've still got to define the keys I need for the final object
James Forbes
@JAForbes
Aug 02 2016 15:41
It'd be easy if the key didn't need to change, or if ramda had a rename key fn
It'd be evolve+pick
Brad Compton (he/him)
@Bradcomp
Aug 02 2016 15:42
There's a renameKeys function in the cookbook!
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 15:42
ya
hah thanks @Bradcomp.
Denis Stoyanov
@xgrommx
Aug 02 2016 15:43
yes, cookbook really helpful
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 15:48
Does Ramda have a twitter?
Denis Stoyanov
@xgrommx
Aug 02 2016 15:49
@aaronmcadam https://twitter.com/scott_sauyet https://twitter.com/davidchambers
Michael Hurley
@buzzdecafe
Aug 02 2016 17:04
@xgrommx ..
.... and
Twitter.com/_schristo
Etc
Rafe
@rjmk
Aug 02 2016 17:43
@JAForbes On your gist with ap, the issue is to do with arities. I think this may actually be a bug in the implementation of ap -- the resulting function is curried to have arity equal to the max of the first or the second function, but I think one needs to be deducted from the first function.
Anyway, you can fix your example by wrapping R.flip(R.dissoc) like so : R.curryN(1, R.flip(R.dissoc))
Denis Stoyanov
@xgrommx
Aug 02 2016 17:54
Looks like reduceRight in ramda doesn't correct also this problem with standard version of reduceRight My version works as in haskell. http://goo.gl/zSfQaa
David Chambers
@davidchambers
Aug 02 2016 18:01
@xgrommx and @buzzdecafe, it's easier to send people to the Core Team page on the wiki. ;)
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 18:06
// this works
 const fetchResponse = (responseId, projectId) => (
  fetchData(responseId, projectId)
   .then(R.apply(mapResponse))
);

// this doesn't
const fetchResponse = R.composeP(
  R.apply(mapResponse),
  fetchData
);
Denis Stoyanov
@xgrommx
Aug 02 2016 18:07
@aaronmcadam what is a mapResonse?
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 18:07
Can i not use apply in a pipeline like this?
export const mapResponse = (response, { questions, assets, participant }) => ({
  id: response.id.toString(),
  …
Denis Stoyanov
@xgrommx
Aug 02 2016 18:07
@aaronmcadam you need use kleisli probably
@aaronmcadam composeK
@ram-bot composeK
Aaron Mc Adam
@aaronmcadam
Aug 02 2016 18:08
Why though?
I've got the docs, thanks :)