These are chat archives for ramda/ramda

16th
Feb 2017
Andrew
@foiseworth
Feb 16 2017 08:20
Can anyone possibly show me how to make this function so I can curry the appId variable? I've been trying on and off for two days :tired_face: https://goo.gl/zILTgI
Adam Szaraniec
@mimol91
Feb 16 2017 08:23
I m not ramda expert
But I guess you should use http://ramdajs.com/docs/#flip
This message was deleted
const getBoxesForApp = (boxes) => (appId) => 
   keys(filter(box => contains(appId, box.applications), boxes))
Andrew
@foiseworth
Feb 16 2017 08:26
^ that is definitely better, thanks :)
Vincent Orr
@Cmdv
Feb 16 2017 09:38

how would you go about turning this:

[{title: "Sat Feb 20 2017", name:"bob"},
 {title: "Sat Feb 18 2017", name:"bob1"},
 {title: "Sat Feb 18 2017", name:"bob2"}]

matching duplicate title and putting into their own object so it looks likes:

[{
  index: 0,
  title: "Sat Feb 20 2017",
  people: [
    {title: "Sat Feb 20 2017", name:"bob"}
  ]
 },
 {
  index: 1,
  title: "Sat Feb 18 2017",
  people: [
   {title: "Sat Feb 18 2017", name:"bob1"},
   {title: "Sat Feb 18 2017", name:"bob2"}
 ]
 }]
λ • Geovani de Souza
@geovanisouza92
Feb 16 2017 10:02
@Cmdv didn't figured out yet about the index
const f = R.compose(
  R.map(
    R.applySpec({
      title: R.head,
      people: R.compose(R.flatten, R.tail)
    })
  ),
  R.toPairs,
  R.groupBy(R.prop('title'))
)

const a = [{title: "Sat Feb 20 2017", name:"bob"},
 {title: "Sat Feb 18 2017", name:"bob1"},
 {title: "Sat Feb 18 2017", name:"bob2"}]

f(a)
λ • Geovani de Souza
@geovanisouza92
Feb 16 2017 10:15
const f = R.compose(
  R.addIndex(R.map)((it, i) => R.assoc('index', i, it)),
  R.map(
    R.applySpec({
      title: R.head,
      people: R.compose(R.flatten, R.tail)
    })
  ),
  R.toPairs,
  R.groupBy(R.prop('title'))
)

const a = [
  {title: "Sat Feb 20 2017", name:"bob"},
  {title: "Sat Feb 18 2017", name:"bob1"},
  {title: "Sat Feb 18 2017", name:"bob2"}
]

f(a)
Vincent Orr
@Cmdv
Feb 16 2017 10:17
@geovanisouza92 sweet thanks a lot that works great :)
@geovanisouza92 how would I make the index a string?
Vincent Orr
@Cmdv
Feb 16 2017 10:24
got it not to worry :)
Adam Szaraniec
@mimol91
Feb 16 2017 11:46
This message was deleted
Bravi
@Bravilogy
Feb 16 2017 12:50
guys, what's the alternative to concat which would let me append a string at the end of the target?
I know I can do concat(__, '.') but was wondering if there is an actual function for this
Adam Szaraniec
@mimol91
Feb 16 2017 13:06
flip ?
var append = R.flip(R.concat);
Denis Stoyanov
@xgrommx
Feb 16 2017 13:42
this is normal case if u need to reverse your arguments. Usually u can use flip or C combinator
Adam Szaraniec
@mimol91
Feb 16 2017 13:46
const printer = curryN(3, (a,b,c) => {
  return `A: ${a}, B: ${b}, C: ${c}`
})

const flipped = flip(printer)
flipped(1,2,3) //2,1,3

foo(1,2,3)   (3,2,1)
How can I write foo ?
can I use _ ?
Denis Stoyanov
@xgrommx
Feb 16 2017 13:49
firstly u can use (...args)=> f(...args.reverse())
dirty hack))
sorry I'm from phone 📱
Adam Szaraniec
@mimol91
Feb 16 2017 13:49
I mean is there some magic function in ramda?
Denis Stoyanov
@xgrommx
Feb 16 2017 13:50
or some composition of flip
Adam Szaraniec
@mimol91
Feb 16 2017 13:50
flipArgs({1:2, 2:3, 3:1}(fn)
where as first argument u pass mapping
Denis Stoyanov
@xgrommx
Feb 16 2017 13:50
I cannot to check it now
Bravi
@Bravilogy
Feb 16 2017 16:13
hey guys :D
one more issue I stumbled upon and I'm tearing my hair out here

so basically I have a mapping of characters, for example:

const mappings = {
   a: 'z',
   b: 'x',
   c: 'y'
}

and I have an 'encrypted' sentence:

djakldji dqjwodqjwdxzjc qwdojqpw.

I want to replace each character based on mappings. My code at the moment looks like this:

const sentence = 'djakldji dqjwodqjwdxzjc qwdojqpw.';

const replaceChars = char => R.replace(char, mappings[char], sentence);

const app = R.compose(R.map(R.compose(replaceChars, R.toLower)), R.match(/\w/g));
but obviously this doesn't work as expected because I'm mapping over each character and therefore getting this huge array
and also the replace doesn't work because R.replace needs a regex with /g flag right?
Bravi
@Bravilogy
Feb 16 2017 16:30
yayy got it
Galileo Sanchez
@galileopy
Feb 16 2017 16:50
what if you've got a:b b:c, and a string "ab", would this happen? "ab" > "bb" > "cc", wouldn't it?
Przemysław Fałowski
@przemkow
Feb 16 2017 16:51

Hi guys! I have a question a problem with side effects in ramda and i can not find any way to get ride of it...
let's say that my case looks like that:

We want to find a happy person and assign it to this.happyPerson scope. My Code looks like that :

const isHappy =  (obj) => R.equals("HAPPY", obj.mood);
const isHappyPerson = isHappy
this.happyPerson = R.find(isHappyPerson, people);

After a while we have noticed that the is existing sadPerson object which can not live next to happy person

this.sadPerson = {
    name: "Sad Tom"
    helloMessage: "boo... everything sucks"
}

So my solution to remove this guy was like this:

const isHappy =  (obj) => R.equals("HAPPY", obj.mood);
const isHappyPerson = R.ifElse(isHappy,
        () => {
          this.sadPerson = {};
          return true;
        },
        R.F);
this.happyPerson = R.find(isHappyPerson, people);

but like that isHappyPerson function starts to have side effects because i modify there this.sadPerson object which is in upper scope... who could i get ride of this side effect in my function? is there any better operator which would allow me to reset this variable when first one was found?
In my app this problem is much more complicated and i need to iterate trough nested objects to find a proper one, (happy Person can contain sadPerson sometimes and then we want both of them to be assign, if happyPerson do not contains sadPerson we want to reset this guy like above and so on) that's why i would like to avoid iterating thought that object for the second time like that:

if(this.happyPerson.hasSadPerson){
 this.sadPerson = R.find(isSadPerson, this.happyPerson.personsArray)
}
Bravi
@Bravilogy
Feb 16 2017 16:53
@galileopy it would yes. And that's what I'm trying to solve now
Galileo Sanchez
@galileopy
Feb 16 2017 16:53
@Bravilogy what would you like like to have from mappings = {a: "b", b: "c"} and src = "ab",
@Bravilogy is the string "bc" the result?
Bravi
@Bravilogy
Feb 16 2017 16:54
yeah
@galileopy the route I'm taking at the moment is using React. each character will be a component and shouldComponentUpdate will always return false and therefore the same character will not be updated
Galileo Sanchez
@galileopy
Feb 16 2017 16:56
why?
Bravi
@Bravilogy
Feb 16 2017 16:56
I'm using reducer to keep replacing whatever is inside the mappings object
should I not?
Galileo Sanchez
@galileopy
Feb 16 2017 16:56
Why solve such a simple problem with react?
Bravi
@Bravilogy
Feb 16 2017 16:57
I couldn't find any other solutions :D

the problem is when we have

const mappings = {
   i: 'v',
   v: 's'
}

what will happen is all i characters will be replaced with v and then these replaced v characters will be replaced with s afterwards

Alexander Doroshenko
@aledoroshenko
Feb 16 2017 17:01
Guys, what's the right way _.sample like Lodash do? To get random element of collections.
Galileo Sanchez
@galileopy
Feb 16 2017 17:01
const mapChars = R.compose(join(""), map(prop(__, mappings)))
const mappings = {a: "b", b: "c"}
const sentence = 'ab';
const mapChars = compose(join(""), map(prop(__, mappings)))
mapChars(sentence)
@ram-bot
how do I make rambot eval stuff?
Bravi
@Bravilogy
Feb 16 2017 17:03
@galileopy ah one thing I haven't mentioned (sorry, my bad) is that there will be characters that are not in the mappings object
and they need to be left as they are
Galileo Sanchez
@galileopy
Feb 16 2017 17:04
so you change prop to propOr
Bravi
@Bravilogy
Feb 16 2017 17:04
propOr
hmm
didn't know that one
I'll have a look now, thanks
but that piece of code is very useful, thank you
Denis Stoyanov
@xgrommx
Feb 16 2017 17:05
swap value in js var {a:b, b:a} = {a:10, b:20}
Brad Compton (he/him)
@Bradcomp
Feb 16 2017 17:06
@ram-bot
const mappings = {a: "b", b: "c"}
const sentence = 'ab';
const mapChars = compose(join(""), map(prop(__, mappings)))
mapChars(sentence)
ram-bot
@ram-bot
Feb 16 2017 17:06
'bc'
Brad Compton (he/him)
@Bradcomp
Feb 16 2017 17:08
@galileopy like that :)
Denis Stoyanov
@xgrommx
Feb 16 2017 17:09
filterWithKey and values with join will be awesome
or just reduce with hasKey
Bravi
@Bravilogy
Feb 16 2017 17:10
@ram-bot
const mappings = { a: 'b', b: 'c' };
const sentence = 'abdjasd';
const mapChars = compose(join(''), map(x => propOr(x, __, mappings)(x)));
mapChars(sentence)
ah
@ram-bot
const mappings = { a: 'b', b: 'c' };
const sentence = 'abdjasd';
const mapChars = compose(join(''), map(x => propOr(x, __, mappings)(x)));
mapChars(sentence)
ram-bot
@ram-bot
Feb 16 2017 17:11
'bcdjbsd'
Bravi
@Bravilogy
Feb 16 2017 17:11
yayy
Galileo Sanchez
@galileopy
Feb 16 2017 17:17
const mappings = {a: "b", b: "c"}
const sentence = 'ab';
const getChar = lift(propOr) (identity, identity, always(mappings))
const mapChars = R.compose(join(""), map(getChar))
mapChars(sentence)
TIL that conver and lift are swappable
converge
Bravi
@Bravilogy
Feb 16 2017 17:26
@galileopy don't quite understand how this one works. I thought lift received only one function
and then a few arrays, as per example
Galileo Sanchez
@galileopy
Feb 16 2017 17:32
i think converge is clearer in this case converge(propOr, [identity, identity, always(mappings)])
@Bravilogy I only have an intuition of how lift works in this case, just learned that lift can cover converge use cases, but the reason as of why are hard for me to explain, it probably is because functions are applicatives or functors on their own so it works by applying stuff around in some obscure way
Bravi
@Bravilogy
Feb 16 2017 17:35
I just realised http://stackoverflow.com/questions/36558598/cant-wrap-my-head-around-lift-in-ramda-js from this post that lift actually relies on .ap
hah
Galileo Sanchez
@galileopy
Feb 16 2017 17:36
@przemkow you could make a function that takes an array of person and returns {happyPerson: value, sadPerson: {}} or {} in case you don't find any
and then merge (this, result)
I'm not comfortable using this because it leads you to side efects
Bravi
@Bravilogy
Feb 16 2017 17:55
const add = lift((a, b) => a + b);
console.log(add([1, 2], [3, 4]));
it makes me think that arrays implement .ap by default in JS
what the hell :D
Rick Medina
@rickmed
Feb 16 2017 18:17
@Bravilogy is implemented in terms of reduce (not the native one though) -not adding ap to the prototype or something like that
Rick Medina
@rickmed
Feb 16 2017 19:32
@galileopy the cool thing about this math based (category theory) interface design is that a few of these concepts are applied to a lot of stuff and can be rapidly composed to solve wildly different problems. So once you learn a few fundamental principles you can apply them and derive all sorts of things. I like lift (vs converge) because it can be used to all (applicative) functors (yes, functions are applicative functors) so I don't have to remember a specific function name to just do what I want to do. I just remember a few of these and compose from there on.
mapping a function is just function composition (with 2 functions) and would be same as a 1 arity lift.
Johnny Hauser
@m59peacemaker
Feb 16 2017 21:27
Anyone have the most direct fancy Ramda way to make the first thing into the second thing?
{
  foo: {
    a: 'a',
    b: 'b',
    c: 'c',
    d: 'd'
  }
}

{
  foo: {
    a: 'a',
    b: 'b'
  },
  qux: {
    c: 'c',
    d: 'd'
  }
}
I need to transfer ['c', 'd'] from foo to qux
Johnny Hauser
@m59peacemaker
Feb 16 2017 22:34
Not very simple - https://goo.gl/5Jgglm
Keith Alexander
@kwijibo
Feb 16 2017 22:38
@m59peacemaker some things are simpler with object destructuring
Johnny Hauser
@m59peacemaker
Feb 16 2017 22:39
Can you show me an example of what you have in mind?
Brad Compton (he/him)
@Bradcomp
Feb 16 2017 22:45
Johnny Hauser
@m59peacemaker
Feb 16 2017 22:45
woaaahhhh man
Brad Compton (he/him)
@Bradcomp
Feb 16 2017 22:46
:point_up: I like the idea of using a lens though
Johnny Hauser
@m59peacemaker
Feb 16 2017 22:46
mine was wrong, btw. It overwrote qux
Brad Compton (he/him)
@Bradcomp
Feb 16 2017 22:48
Johnny Hauser
@m59peacemaker
Feb 16 2017 22:48
It must be awesome being a genius =D
Brad Compton (he/him)
@Bradcomp
Feb 16 2017 22:48
:(
I wouldn't know ;)
Johnny Hauser
@m59peacemaker
Feb 16 2017 22:49
psshhhhh
Any reason to use the lens twice rather than:
converge(
  assoc('qux'), [
    compose(pick(['c', 'd']), R.prop('foo')), 
    over(lensProp('foo'), omit(['c', 'd']))
  ]
)(x)
Brad Compton (he/him)
@Bradcomp
Feb 16 2017 22:51
Nah, just because I had it
Also, it would allow you to generalize the function to pass in an arbitrary lens if you wanted
Johnny Hauser
@m59peacemaker
Feb 16 2017 22:53
const transferPropsFromLens = (props, lensA, lensB) => {}
something like that?
Brad Compton (he/him)
@Bradcomp
Feb 16 2017 22:56
yes!
Johnny Hauser
@m59peacemaker
Feb 16 2017 23:02
That needs to be on npm!
But first, Ramda needs to be appropriately modularized
Is there anything stopping me from implementing that and submitting a PR right now?
oh wait ramda/ramda#1959
That needs to happen, really badly..
Brad Compton (he/him)
@Bradcomp
Feb 16 2017 23:07
Maybe a good one for the cookbook
Johnny Hauser
@m59peacemaker
Feb 16 2017 23:12
Does Ramda need more maintainers?
Johnny Hauser
@m59peacemaker
Feb 16 2017 23:20
Oh yeah, it's just the src in the require path. I was thinking the problem was worse.
Johnny Hauser
@m59peacemaker
Feb 16 2017 23:40
@Bradcomp could you write some comments to help me understand how this converge business works? I'm still not getting it.
Brad Compton (he/him)
@Bradcomp
Feb 16 2017 23:46
I'm on my phone right now, but basically the object gets passed through each function in the array. The results of the calls to those functions get passed into the set call at the end.
Galileo Sanchez
@galileopy
Feb 16 2017 23:46
@rickmed I'm really starting to get fond of the idea of learning something more hardcore about category theory, but I'm not there yet.
Johnny Hauser
@m59peacemaker
Feb 16 2017 23:48
@Bradcomp That explanation was easy enough!
Why doesn't this produce the same result? arg => set(toLens)(arg)
the result is a function
Galileo Sanchez
@galileopy
Feb 16 2017 23:49
maybe there is a mild step into it without going full math mode on? btw TIL that you can implement a web server with eventStreams rather quickly, which is nice, since most of the time I spend is on interfacing things to work as composable as I can but returning something that can be put as an express middleware
Johnny Hauser
@m59peacemaker
Feb 16 2017 23:53
man that's perplexing. set(toLens) and arg => set(toLens)(arg) look identical to me
Galileo Sanchez
@galileopy
Feb 16 2017 23:54
@Bradcomp anyttime you find yourself doing this fn(help1(arg1, arg2, arg3), help2(arg1, arg2, arg3) ...., helpN(arg1, arg2, arg3)) you are converging to that function,
@m59peacemaker doesn't set require 3 arguments?
Johnny Hauser
@m59peacemaker
Feb 16 2017 23:54
Oh doh
Galileo Sanchez
@galileopy
Feb 16 2017 23:55
:)
Johnny Hauser
@m59peacemaker
Feb 16 2017 23:56
I got stupid and was thinking of the lens at the data itself
Galileo Sanchez
@galileopy
Feb 16 2017 23:56
@Bradcomp and with nthArg and identity you can start doing all sorts of interesting stuff too
@Bradcomp when using them with converge
I'm reading into composeP, is that something like compose with auto liftiing to promises?