These are chat archives for ramda/ramda

10th
Sep 2017
Kurt Milam
@kurtmilam
Sep 10 2017 11:32
@buzzdecafe Thanks! I had considered asking how to get rid of the unnest there. I had played with a few combinations, but hadn't hit the right one. I don't like seeing unnest in my code, and figure there's usually a way to avoid it, but I'm not always successful in my endeavors to that end.
With that in mind, does anyone have an idea how I can get rid of the unnest in my mirrorPivot function here?
Philipp Wille
@Yord
Sep 10 2017 12:01
@kurtmilam How about:
const mirrorPivot = converge(concat, [identity, o(reverse, init)])
Kurt Milam
@kurtmilam
Sep 10 2017 12:05
@Yord that was easy! :D
Thanks. I had tried several combinations based on concat, but somehow missed the obvious one.
Here's an updated REPL with both juxts replaced with converge. Thanks again!
Philipp Wille
@Yord
Sep 10 2017 12:10
@kurtmilam Happy to help! :)
Michael Hurley
@buzzdecafe
Sep 10 2017 12:16
anytime I see converge with identity in the first position, I think "I can probably rewrite that with chain"; sure enough: chain(flip(concat), o(reverse, init))
Kurt Milam
@kurtmilam
Sep 10 2017 12:19
@buzzdecafe Now that's what I'm talking about. I'll spend some time figuring out how that's a valid replacement for the converge- and juxt-based solutions, and I'll try to keep that rule in mind in the future. Thanks!
Michael Hurley
@buzzdecafe
Sep 10 2017 12:20
:+1:
Kurt Milam
@kurtmilam
Sep 10 2017 12:50
@buzzdecafe Thanks again - I have never taken advantage of the way chain works when the first two arguments are functions. Unfortunately, although I get what's happening there, I'm still not 100% sure why/how it's happening, even after reading the docs for chain and the linked fantasyland spec. Are you aware of any other writing that explains how this works in more detail, because it's very useful, and I'd like to really internalize how it's doing what it's doing.
Michael Hurley
@buzzdecafe
Sep 10 2017 12:52
i wrote a post about it a while ago: http://buzzdecafe.github.io/2016/12/29/chain-chain-chain
nice thing is how simple the implementation of the function instance of chain is: https://github.com/ramda/ramda/blob/v0.24.1/src/chain.js#L32
Kurt Milam
@kurtmilam
Sep 10 2017 13:12
Thanks again for both links. I should have gone straight to the source (I usually do), but I appreciate the link to your article on the topic, as well!
Michael Hurley
@buzzdecafe
Sep 10 2017 13:14
yw
Jonah
@jonahx
Sep 10 2017 20:09

@buzzdecafe, Not being familiar with that slick use of chain, I would have done:

const xs = [1,2,3]
converge(append, [head, identity])(xs)

Is there any sense in which chain is special case of converge, or vice-versa? Can you speak to the appropirateness — semantically, or otherwise — of using one method over the other?

Michael Hurley
@buzzdecafe
Sep 10 2017 21:15
that looks like a perfectly fine solution. what interests me is that this converge(append, [head, identity])(xs) and mirrorPivot can be solved with the same abstraction.
that suggest to me that there is something to that pattern, and i should try to recognize it.
but i don't think there is anything inappropriate about converge(append, [head, identity]).
Jonah
@jonahx
Sep 10 2017 21:54
@buzzdecafe, yeah, this pattern (in the two argument form) is considered so important in J that it's baked right into the language syntax — it’s called a fork. so +/ % # is the J verb for “average”. the middle % is division, +/ is sum, and # is length. so you pass it a list, and those two things on the side get executed first (just like the array of transformers in converge, but with a nicer visual metaphor), and the the results are passed to “divide”. And note you don’t have to tell it to do that: any time you have 3 verbs in a row, it automatically works like that.
Michael Hurley
@buzzdecafe
Sep 10 2017 21:59
interesting, i am not familiar with J.
Jonah
@jonahx
Sep 10 2017 22:00
@buzzdecafe, yeah, just mentioning it as anecdotal evidence that your inuition about the pattern being important is probably correct
unrelated question: why in haskell is ap defined for Monads, but in ramda it is defined for Applys?
Michael Hurley
@buzzdecafe
Sep 10 2017 22:03
good question, I don't think I can give you a good answer. in this case we are hewing closer to Fantasy-Land spec, rather than Haskell.
why FL diverged from Haskell definition I do not know
Jonah
@jonahx
Sep 10 2017 22:06
@buzzdecafe would @davidchambers know, or someone else?
Michael Hurley
@buzzdecafe
Sep 10 2017 22:07
maybe; he is closer to FL spec than I am
Jonah
@jonahx
Sep 10 2017 22:16
also: in ramda, what are the equivalents (if any) of haskell’s <$> and <*> for applicatives?
Michael Hurley
@buzzdecafe
Sep 10 2017 22:25
<$> is infix map, yes? So map(inc, Just(1)) returns Just(2). can't get the infix syntax unfortunately
and i believe ap is prefix synonym of <*>, e.g. ap(Just(inc), Just(1)) returns Just(2)