These are chat archives for ramda/ramda

23rd
May 2017
Stephan Meijer
@smeijer
May 23 2017 07:37
How would one solve this issue with Ramda? Can the nested ternary be fixed more nicely?
const commentIds = [1,2,3];
const fileIds = [4,5,6];

const newResult = results.map(x => ({
  ...x,
  source:
    regexp.test(x.title) ? 'title' :
    R.contains(x._id, commentIds) ? 'comments' :
    R.contains(x._id, fileIds) ? 'attachments' :
    'fulltext',
}))
Denis Stoyanov
@xgrommx
May 23 2017 09:04
@ram-bot
const intersection_ = (a, b) => a.filter(Set.prototype.has, new Set(b))
intersection_([1,2,3], [1,2])
Michael Zinn
@RedNifre
May 23 2017 12:03
Greetings! Not sure if this is of relevance to anybody here but I began porting Ramda to Java: https://github.com/RedNifre/ravr
So if you're ever forced to write Java for whatever reason you can still use a bit of Ramda :smile:
Gabe Johnson
@gabejohnson
May 23 2017 12:45
@RedNifre very cool!
Tom Harding
@i-am-tom
May 23 2017 12:47

Aw yiss

Does it play nicely with http://www.functionaljava.org/ ?

Really exciting to see these utility belts appearing in different languages. Gives me hope, hah
Michael Zinn
@RedNifre
May 23 2017 12:50
Yeah, I got inspired by how this whole ReactiveX thing works in every language (RxJava, RxKotlin...). I had a look at functionaljava but I decided that vavr is the same thing but better so right now Ravr only works on Ravr data types.
Tom Harding
@i-am-tom
May 23 2017 12:50
aah, nice!
Michael Zinn
@RedNifre
May 23 2017 12:51
I meant Ravr only works on vavr data types.
Tom Harding
@i-am-tom
May 23 2017 12:51
Yeah, hah
Michael Zinn
@RedNifre
May 23 2017 12:52
I noticed that the Ramda documentation is available as JSON. Is that also MIT licensed i.e. could I generate Ravr Javadoc from that?
Gabe Johnson
@gabejohnson
May 23 2017 12:53
A coworker just pointed me to https://github.com/andrewoma/dexx
Had no idea Java was sucking so much less
Liam Goodacre
@LiamGoodacre
May 23 2017 12:54
Hey, I have an issue with ramda's traverse/sequence: the docs reference fantasyland Applicative https://github.com/fantasyland/fantasy-land#apply which has ap :: Apply f => f a ~> f (a -> b) -> f b, but the Ramda's sequence appears to assume: ap :: Apply f => f (a -> b) ~> f a -> f b
Tom Harding
@i-am-tom
May 23 2017 12:55
The order of arguments got changed… at some point
Gabe Johnson
@gabejohnson
May 23 2017 12:56
When FL v1 was released
Liam Goodacre
@LiamGoodacre
May 23 2017 12:56
because that means it no-longer respects the fantasylang spec
land*
Michael Zinn
@RedNifre
May 23 2017 12:56
@gabejohnson Well, that's Kotlin, but if you want to write Java code with val etc. you should checkout Lombok https://projectlombok.org/features/Data.html
Gabe Johnson
@gabejohnson
May 23 2017 12:56
Ramda should be compliant after the next release
Tom Harding
@i-am-tom
May 23 2017 12:57
A lot of the older fantasy types are the wrong way round, too. My todo list has an entry for updating and documenting them
Michael Zinn
@RedNifre
May 23 2017 12:57
Hm, doesn't f (a -> b) -> f a -> f b make more sense for currying?
Tom Harding
@i-am-tom
May 23 2017 12:57
That’s a whole can o’ worms that many have opened
Michael Zinn
@RedNifre
May 23 2017 12:57
Well, why not make a fantasyland 2.0 standard that's incompatible and has everything in the right order?
Gabe Johnson
@gabejohnson
May 23 2017 12:57
@RedNifre that's still the signature for delegating functions
the method is f a ~> f (a -> b) -> f b

why not make a fantasyland 2.0 standard

FL is at version 3.3

Tom Harding
@i-am-tom
May 23 2017 12:59
inb4 “fantasyland 4.0” - I think the point was unconcerned with the version number :p
Gabe Johnson
@gabejohnson
May 23 2017 13:08
@xgrommx you should add Eta to that list
@RedNifre @i-am-tom I'm not sure what the right order is
Denis Stoyanov
@xgrommx
May 23 2017 13:09
@gabejohnson welcome to PR :smile: (I know about eta, I have some example with recursion-schemes)
Gabe Johnson
@gabejohnson
May 23 2017 13:09
:thumbsup:
Tom Harding
@i-am-tom
May 23 2017 13:10
f a b
(pure f)  <$> (pure a) <*> (pure b)
There’s definitely an order that makes more intuitive sense imo
Tom Harding
@i-am-tom
May 23 2017 13:11
Quite
Gabe Johnson
@gabejohnson
May 23 2017 13:15

@i-am-tom my Haskell/PureScript is not so good. That looks like

ap(map(of(f)), of(b));

to me

Tom Harding
@i-am-tom
May 23 2017 13:15
yeah
f(a)(b)
pure(f).ap(a).ap(b)
Gabe Johnson
@gabejohnson
May 23 2017 13:18

but instead we have

b.ap(a.ap(pure(f)))

?

Tom Harding
@i-am-tom
May 23 2017 13:18
yeah
Gabe Johnson
@gabejohnson
May 23 2017 13:20
It seems FL is very dispatch oriented. Not very fluent friendly anymore
Tom Harding
@i-am-tom
May 23 2017 13:20
Yeah. It’s not an actual problem, but it makes it hard to introduce people when, by intuition, stuff’s backwards
Gabe Johnson
@gabejohnson
May 23 2017 13:21
By intuition for a Haskeller
Liam Goodacre
@LiamGoodacre
May 23 2017 13:21
b.ap(a.ap(pure(f))) isn't right is it? the order of combination isn't flipped, just the indices? no?
Tom Harding
@i-am-tom
May 23 2017 13:21
No no, for JavaScripters - left-to-right argument order
@LiamGoodacre That is indeed right
Granted, it’s not perfect, because after doing pure(f).ap(a).ap(b), you immediately realise that homomorphism means you can write a.map(f).ap(b) (or b.ap(a.map(f)) in our case) and you’re back to obfuscation, but there was at least a sense of direction on the way
Liam Goodacre
@LiamGoodacre
May 23 2017 13:23
I'm currently using a.ap(b.map(x => y => y(x))) to flip the indicies
Denis Stoyanov
@xgrommx
May 23 2017 13:24
I like haskell's version
Tom Harding
@i-am-tom
May 23 2017 13:24
Honestly, I just write lift2 and forget about it. I’m learning that it is best to introduce things via helper functions
Denis Stoyanov
@xgrommx
May 23 2017 13:25
liftA = fmap
liftA2 = liftA + ap
liftA3 = liftA2 + ap
liftAn = liftA(n - 1) + ap
Liam Goodacre
@LiamGoodacre
May 23 2017 13:26
my issue is that I'm writing in typescript and the fantasyland spec is easy to implement with a ts interface, but the current way that ramda expects ap is more difficult to describe
Tom Harding
@i-am-tom
May 23 2017 13:26
Mhm :/
Denis Stoyanov
@xgrommx
May 23 2017 13:27
yes, lift is avesome
Liam Goodacre
@LiamGoodacre
May 23 2017 13:27
so I've written a nasty untyped wrapper class that flips the indices just to work with ramda :smile:
Denis Stoyanov
@xgrommx
May 23 2017 13:27
also with join (chain(identity)) we can do join(liftA2(*)) [10] is like liftA2(*) [10] [10]
Joey Figaro
@joeyfigaro
May 23 2017 14:28
Morning all. Silly question - how might I go about getting the sum of the keys in an array of objects? [{ users: 34 }, { users: 1239 }, { users: 129 }]
James Forbes
@JAForbes
May 23 2017 14:29
sum of the keys?
oh like in that case 3?
or the sum of a value with a shared key?
Joey Figaro
@joeyfigaro
May 23 2017 14:30
sum of the value with a shared key - want to get the total value of users in that array.
34 + 1239 + 129
James Forbes
@JAForbes
May 23 2017 14:31
ok so first thing you may want to do is pluck('users')
Joey Figaro
@joeyfigaro
May 23 2017 14:31
The objects have other keys as well, but I omitted them.
James Forbes
@JAForbes
May 23 2017 14:31
Then take the sum
Joey Figaro
@joeyfigaro
May 23 2017 14:31
Man, pluck. Forgot about that'n.
So, map over the array, pluck users, sum.
James Forbes
@JAForbes
May 23 2017 14:32
compose( sum, pluck('users') )(array)
skip the "map over the users" step, that's already built into pluck
Joey Figaro
@joeyfigaro
May 23 2017 14:33
Just saw that pluck gets me a new list - :)
Thanks man!
James Forbes
@JAForbes
May 23 2017 14:33
My pleasure :D
Rick Medina
@rickmed
May 23 2017 14:33
forgot about pluck too :) was recommending reduce...
James Forbes
@JAForbes
May 23 2017 14:34
well reduce might save an iteration, what were you going to suggest @rickmed
James Forbes
@JAForbes
May 23 2017 14:41
nah pretty good
Rick Medina
@rickmed
May 23 2017 14:41
reduce((a, x) => pipe(prop('users'), add(a))(x), 0)
deleted on accident...
Joey Figaro
@joeyfigaro
May 23 2017 18:37
Anyone wanna take a crack at/offer some insight on combining some of this? https://goo.gl/22cAe4
I've got an array of objects, and need to pull out totals for this month, last month, last six months, and total in all. I've got the total in all done and have figured out how to use head and tail to piece together the different sets of months.
I was thinking it'd be better to update calculateTotal to take the selection of months into account instead of having three different functions for handling it.
Brad Compton (he/him)
@Bradcomp
May 23 2017 18:45
Maybe consider just composing your totalling function with take and drop
This month is compose(calcTotal, take(1)), last month is compose(thisMonth, drop(1)), etc...
Joey Figaro
@joeyfigaro
May 23 2017 18:46
I hadn't even considered that Brad - thank you. :)
Brad Compton (he/him)
@Bradcomp
May 23 2017 18:47
composition FTW :stuck_out_tongue:
Joey Figaro
@joeyfigaro
May 23 2017 18:49
Yeah, I'm still wrapping my head around it.
Joey Figaro
@joeyfigaro
May 23 2017 18:58
@Bradcomp how do you end up dealing with a curried function inside of compose?
Luke Jackson
@lukejacksonn
May 23 2017 19:05
:wave: could anyone explain to me any differences between these two lines (mostly interested in performance), is one much better/worse than the other?
R.set(R.lensPath(['a']), val, state)
R.assocPath(['a'], val, state)
Brad Compton (he/him)
@Bradcomp
May 23 2017 19:06
lensPath uses assocPath internally, so assocPath will by definition have less overhead
Luke Jackson
@lukejacksonn
May 23 2017 19:06
:+1:
Brad Compton (he/him)
@Bradcomp
May 23 2017 19:10
@joeyfigaro What do you mean? https://goo.gl/1hxV7V
Kurt Milam
@kurtmilam
May 23 2017 19:20
@lukejacksonn you might be interested in some of the benchmarks here. R.assocPath and R.set are covered , as are a number of other Ramda methods.
Joey Figaro
@joeyfigaro
May 23 2017 19:22
@Bradcomp I think I'm frequently overcomplicating this. :P
Thank you for the help!
I was attempting to compose calculateTotal
And was getting strings back (from take/drop) according to the property I was passing in for pluck. So, I'd get something like u - heeehhh
(from users)
Luke Jackson
@lukejacksonn
May 23 2017 19:36
@kurtmilam thanks, that is awesome!
Kurt Milam
@kurtmilam
May 23 2017 19:56
You bet! I'm a big fan of the partial.lenses library (where the benchmark results are hosted), as well.
Brad Compton (he/him)
@Bradcomp
May 23 2017 19:57
@joeyfigaro You can get rid of the calculateTotal too! https://goo.gl/rMQ65u
Luke Jackson
@lukejacksonn
May 23 2017 19:57
yeh.. there are some significant differences there!
Liam Goodacre
@LiamGoodacre
May 23 2017 20:16
@lukejacksonn nice seeing you here :smile:
Denis Stoyanov
@xgrommx
May 23 2017 20:19
:smile:
Luke Jackson
@lukejacksonn
May 23 2017 20:20
@LiamGoodacre :wave: good to be here.. finally :sweat_smile:
Joey Figaro
@joeyfigaro
May 23 2017 20:26
@Bradcomp You are a wizard.
:100:
Brad Compton (he/him)
@Bradcomp
May 23 2017 20:27
:bowtie:
Liam Goodacre
@LiamGoodacre
May 23 2017 20:27
Going back to my question about R.ap and fantasy-land (I want to make damn sure), am I correct that both should be combining left-to-right? and when R.ap(applyF, applyX) looks for fantasy-land/ap should really be doing: applyF['fantasy-land/ap'](map(x => f => f(x), applyX)) not applyX['fantasy-land/ap'](applyF).
Brad Compton (he/him)
@Bradcomp
May 23 2017 20:28
The sad answer is... it depends
Liam Goodacre
@LiamGoodacre
May 23 2017 20:28
:worried: worrying intensifies
when I implement left['fantasy-land/ap'](right), unless I've missed something, I would expect to combine it in that order left-to-right, regardless of which argument has the function index.
Liam Goodacre
@LiamGoodacre
May 23 2017 20:33
i.e. in the same way that chain would work
Brad Compton (he/him)
@Bradcomp
May 23 2017 20:34
Sorry got sidetracked
of(f).ap(of(x)) is the old version of the spec (pre 1.0), while of(x).ap(of(f)) is the 1.0 + version
It's a can of worms, many people (like me) prefer the old argument order
Liam Goodacre
@LiamGoodacre
May 23 2017 20:37
I don't particularly care about argument order, it's irrelevant (although the newer is nicer to work with in typescript classes), the ordering of combination is what is important.
Brad Compton (he/him)
@Bradcomp
May 23 2017 20:39
What do you mean?
Liam Goodacre
@LiamGoodacre
May 23 2017 20:43
treatment of fantasy-land/ap should be like the Haskell/PureScript: liftA2 (\x f -> f x) :: Apply f => f a -> f (a -> b) -> f b, not flip (<*>) :: Apply => f a -> f (a -> b) -> f b. The arguments are always combined left-to-right, regardless of which one has a/a -> b.
(by "should" I mean, I think it makes more sense)
See the test case I had a go at adding here: https://github.com/ramda/ramda/compare/master...LiamGoodacre:fix/ap
Denis Stoyanov
@xgrommx
May 23 2017 20:49
@LiamGoodacre flip(<*>) isn't correct if u want flipped version of <*> u can liftA2(flip($)) (some interesting moment with ordering of effects) or just use <**> :smile:
@LiamGoodacre regarding ap for function it should be certain as S combinator
Liam Goodacre
@LiamGoodacre
May 23 2017 20:52
"flip (<*>) isn't correct" - that's exactly my point :smile:
Denis Stoyanov
@xgrommx
May 23 2017 20:52
:+1:
Liam Goodacre
@LiamGoodacre
May 23 2017 20:56
I'll open a PR shortly and try to explain it in more detail there
Denis Stoyanov
@xgrommx
May 23 2017 20:57
λ> let x = tell "x" $> 2
λ> let f = tell "f" $> succ
λ> map runWriter [f <*> x, flip (<*>) x f, x <**> f]
[(3,"fx"),(3,"fx"),(3,"xf")]
Liam Goodacre
@LiamGoodacre
May 23 2017 20:59
:+1: