These are chat archives for ramda/ramda

15th
Feb 2018
Brad Compton (he/him)
@Bradcomp
Feb 15 2018 00:04
unnest is equivalent to chain(identity)
joao@kapmug
@jay-jlm
Feb 15 2018 00:15
ok but that's giving me ['a']... how does that + objOf becomes {"a": "a"} is what I dont get
Brad Compton (he/him)
@Bradcomp
Feb 15 2018 00:17
This article is pretty good. It talks about how chain works for functions
joao@kapmug
@jay-jlm
Feb 15 2018 00:19
nice, I will take a look. thanks.
Matthew Willhite
@miwillhite
Feb 15 2018 01:13
@jay-jlm biphub looks like a fun project! I don’t know what kind of TS support Sanctuary would have…I doubt any tbh. I have a project that leans heavily on ramda and it’s been a gradual upgrade to Sanctuary. I just pick a few pieces where I can swap out the API. Also shaping the data with daggy.js and adding those types to the Sanctuary environment. That allows me to go even further and use sanctuary-def to define my public facing functions with type checks
joao@kapmug
@jay-jlm
Feb 15 2018 01:15
I think you wanted to mention @JasonShin
Matthew Willhite
@miwillhite
Feb 15 2018 01:19
oof sorry
joao@kapmug
@jay-jlm
Feb 15 2018 01:21
np
Bijoy Thomas
@bijoythomas
Feb 15 2018 01:23
@Bradcomp thanks!
joao@kapmug
@jay-jlm
Feb 15 2018 02:03
I'm still trying to understand how chain() works
in the linked article, in both examples the last function takes a single parameter
 const f = chain(append, head);
 chain(concat, toLower)("ABCD");
however in the case I'm trying to understand the function signature for the second function is different, and I can confirm with this test that it's being called with two arguments, not one:
const myFunc = R.curry((p1, p2) => {
  console.log(p1, p2) // => "a" "a" 
  return  [p1, p2]
} )
chain(identity, myFunc)('a');
joao@kapmug
@jay-jlm
Feb 15 2018 02:24
also in examples the data seems to flow from the second function to the first one (gets the head then appends it.. lowers it then concats it) but in my example the first function is being called first , cf: https://goo.gl/RABLiS
Bijoy Thomas
@bijoythomas
Feb 15 2018 02:45
@jay-jlm the difference is that the chain(identity)(objOf) returns a function which then needs to be executed. It's an example of the function type being a monad
if you think of functors as boxes that contain stuff, then curried functions can be thought of as boxes that need to be invoked with some argument to extract the contained value
Bijoy Thomas
@bijoythomas
Feb 15 2018 02:52
if you follow the type signature of chain with a function type: chain :: (a -> x -> b) -> (x -> a) -> (x -> b), then identity is the portion a -> x -> b and objOf is the portion x->a. So the expression chain(identity)(objOf) has the type x -> b. So, its a unary function that given an argument returns a value
joao@kapmug
@jay-jlm
Feb 15 2018 02:52
chain(concat, toLower) also needs to be executed.
Bijoy Thomas
@bijoythomas
Feb 15 2018 02:56
so, given x, obj(x) has type a which is passed to a -> x -> b (in our case identity) to yield x -> b, so invoke obj(x) with x and we get b
joao@kapmug
@jay-jlm
Feb 15 2018 02:57
are chain(identity)(objOf) and chain(identity, objOf) equivalent? Because I'm testing with the later, not with the former
Bijoy Thomas
@bijoythomas
Feb 15 2018 02:59
@ram-bot
;[chain(identity)(objOf)('a'),  chain(identity, objOf)('a')]
ram-bot
@ram-bot
Feb 15 2018 02:59
[ { a: 'a' }, { a: 'a' } ]
joao@kapmug
@jay-jlm
Feb 15 2018 02:59
also, can you explain "has a type", is it short for has a return type?
Jason Shin
@JasonShin
Feb 15 2018 03:04
@miwillhite @jay-jlm got it
Bijoy Thomas
@bijoythomas
Feb 15 2018 03:04
no the return type. x -> a is simply a function f that given x returns a. Now if f is a binary function, then a is a unary function which can take one more argument
joao@kapmug
@jay-jlm
Feb 15 2018 03:06
hmm. that's what I just said then. it's the return type.
Bijoy Thomas
@bijoythomas
Feb 15 2018 03:08
f: x -> a is not a return type
its a type signature
joao@kapmug
@jay-jlm
Feb 15 2018 03:09
I wish someone could explain me what is happening behind the scenes in this specific case without the generalizations (the function signatures) cause those have not seem to be helping me in this specific case
yes but you said "has type a" above... that cannot be the whole signature, I suppose.. that's what I was asking about
Bijoy Thomas
@bijoythomas
Feb 15 2018 03:11
My apologies, I'm new to it too and its possible my explanation lacks certain clarity
joao@kapmug
@jay-jlm
Feb 15 2018 03:12
sure, no apologies needed, thanks for trying to help btw
maybe if I peak into the source code of chain I can sort out what it's actually doing :cry:
joao@kapmug
@jay-jlm
Feb 15 2018 03:18
not gonna be easy do.. looks like it's calling a number of other utility functions under the hook , uncluding one called _flatCat
joao@kapmug
@jay-jlm
Feb 15 2018 03:27
on a different subject... I found it curious that the ramda-fantasy readme mentions pretty much every algebraic lib for javascript... except for Monet.js 🤔
Bijoy Thomas
@bijoythomas
Feb 15 2018 13:19
@jay-jlm not sure if this will help but I think chain(f)(g)(x) = (f(g(x)))(x) in the examples you tried
Bijoy Thomas
@bijoythomas
Feb 15 2018 14:24
and ap(f)(g)(x) = (f(x))(g(x)) .. it is interesting to see the flip of the arguments x and g(x)
;[chain(concat, toLower)('ABCD'),  ap(concat, toLower)('ABCD')]
@ram-bot
;[chain(concat, toLower)('ABCD'), ap(concat, toLower)('ABCD')]
ram-bot
@ram-bot
Feb 15 2018 14:25
[ 'abcdABCD', 'ABCDabcd' ]
Brad Compton (he/him)
@Bradcomp
Feb 15 2018 18:53

I wish someone could explain me what is happening behind the scenes in this specific case without the generalizations

chain(identity, objOf)('a');

identity(objOf('a'))('a');

It passes the parameter through the second function passed in, then calls the first function with that, then passes in the second param. It might be helpful to know that this function will work the other way too:

chain(objOf, identity)('a');

objOf(identity('a'))('a');

To get a better feel, try swapping out identity with toUpper in each of the examples and see how it differs.