These are chat archives for ramda/ramda

7th
Oct 2016
Jigar Gosar
@jigargosar
Oct 07 2016 07:41

Please help me to simplify this code. Most of my posts go unanswered :(

   const lastNoteIdxV = compose(dec, view(notesCountL))
    const clampIdx = compose(clamp(0), lastNoteIdxV)
    const currentNoteIdxL = lensProp("currentNoteIdx")
    const updateCurrentNoteIdx = curry((fn, state)=> {
        return over(currentNoteIdxL, compose(clampIdx(state), fn), state)
    })
   // usage
  updateCurrentNoteIdx2(inc)
  updateCurrentNoteIdx2(inc)
  updateCurrentNoteIdx2(always(0))

the clamp method needs to work on lens values, is there some lifting that can be done?
I find using ap and lift very difficult to apply. Not sure if they can be used here.

Scott Christopher
@scott-christopher
Oct 07 2016 08:48
@jigargosar Do you have some example data that you're trying to work with?
Jigar Gosar
@jigargosar
Oct 07 2016 08:50
@scott-christopher yes posting it
@scott-christopher http://pastebin.com/46RcATsv
Jigar Gosar
@jigargosar
Oct 07 2016 08:56
  const noteCountL = lensPath(["notes", "length"])
  const lastNoteIdxV = compose(dec, view(notesCountL))
    const clampIdx = compose(clamp(0), lastNoteIdxV)
    const currentNoteIdxL = lensProp("currentNoteIdx")
    const updateCurrentNoteIdx = curry((fn, state)=> {
        return over(currentNoteIdxL, compose(clampIdx(state), fn), state)
    })
   // usage
  updateCurrentNoteIdx2(inc)
  updateCurrentNoteIdx2(inc)
  updateCurrentNoteIdx2(always(0))
added one missing const noteCountL to the example.
and posting sample data: http://pastebin.com/46RcATsv
Scott Christopher
@scott-christopher
Oct 07 2016 08:58
so you want to be able to update the currentNoteIdx property, clamped to the size of the notes array?
Jigar Gosar
@jigargosar
Oct 07 2016 09:03
yes, thats correct.
but I have keep passing state every where :(
Scott Christopher
@scott-christopher
Oct 07 2016 09:19
If you're interested in using a lens here to represent the index, you're probably better off constructing one using R.lens.
e.g.
@ram-bot
const data = {
   "notes":[
      {"id":0, "title":"1", "body":"a"},
      {"id":1, "title":"2", "body":"b"},
      {"id":2, "title":"3", "body":"c"},
      {"id":3, "title":"4", "body":"d"}
   ],
   "nextNoteID":4,
   "currentNoteIdx":0
}

const lastNotesIdx = compose(dec, length, prop('notes'))
const currentNoteIdxL = lens(
  prop('currentNoteIdx'),
  (v, state) => assoc('currentNoteIdx', clamp(0, lastNotesIdx(state), v), state)
)

const incIdx = over(currentNoteIdxL, inc)
incIdx(incIdx(incIdx(incIdx(data))))
ram-bot
@ram-bot
Oct 07 2016 09:19
{ notes: 
   [ { id: 0, title: '1', body: 'a' },
     { id: 1, title: '2', body: 'b' },
     { id: 2, title: '3', body: 'c' },
     { id: 3, title: '4', body: 'd' } ],
  nextNoteID: 4,
  currentNoteIdx: 3 }
Scott Christopher
@scott-christopher
Oct 07 2016 09:21
I'm sure theres a fancy point-free way to represent the setter of the lens in that example, but it'd probably be more readable by keeping it as an anonymous function anyway.
The main gist of it being that you have a simple property getter, but the setter is capped.
Jigar Gosar
@jigargosar
Oct 07 2016 09:22
@scott-christopher wow, thanks! writing a custom lens that would automatically validate/format values. This is great idea. I can use this at many other places.
and instead of assoc one could also use lensProp("currentNoteIndex") inside custom lens right?
Scott Christopher
@scott-christopher
Oct 07 2016 09:25
you could, but you probably won't gain much because using over and lensProp ends up calling assoc via the implementation of lensProp.
Jigar Gosar
@jigargosar
Oct 07 2016 09:25
I read somewhere that 'assoc' and 'path' are there only for backward compatibality, and not advised to be used.
and lenses are prefered over them.
Scott Christopher
@scott-christopher
Oct 07 2016 09:26
well assoc could be implemented via lensProp ... if we update the implementation of lensProp to not use assoc :)
Jigar Gosar
@jigargosar
Oct 07 2016 09:27
cool, I shall continue to use assoc then. thanks a lot.
Scott Christopher
@scott-christopher
Oct 07 2016 09:27
You're most welcome :) Best of luck with it!
Jigar Gosar
@jigargosar
Oct 07 2016 09:28
@scott-christopher thanks for taking the time to respond, most of the time I don't get any replies. :D
Scott Christopher
@scott-christopher
Oct 07 2016 09:33
Well I'm sorry to hear that. You're welcome to ping me on here if you feel like your questions are going unanswered.
I can't guarantee that I'll always be around the place, but if I am, I'm happy to help :)
Jigar Gosar
@jigargosar
Oct 07 2016 09:34
sure, thanks. Your answers on stackoverflow also have helped me a lot. :)
Markus Pfundstein
@MarkusPfundstein
Oct 07 2016 11:30
lenses are so awesome
:O
Jigar Gosar
@jigargosar
Oct 07 2016 11:30
@MarkusPfundstein +1 :)
Kurt Milam
@kurtmilam
Oct 07 2016 12:41
Looking for some help in converting this to point free:
const complicatedFlatten = expr => 
  R.append(
    getMainValue(expr)
  )(
    getSubValues(expr)
  )
Kurt Milam
@kurtmilam
Oct 07 2016 12:46
Data similar to (but more complex than):
expr = {a:'b', subs: [{a:'c'}, {a:'d'}]}
// and I want to end up with something similar to (but more complicated than):
complicatedFlatten(expr) // outputs:
[{a:'c'}, {a:'d'}, {a:'b'}]
All working at the moment - I'd just like to figure out how to do it point-free.
Jigar Gosar
@jigargosar
Oct 07 2016 14:11

This should work

const complicatedFlatten  = converge(append, getMainValue, getSubValues)

I have struggled a lot with point-free style, with multiple arguments I struggle a lot.
But for a single argument function, converge is your best friend :D

syntax correction: second arg needs to be an array.
const complicatedFlatten  = converge(append,[ getMainValue, getSubValues])
@kurtmilam let me know.
Barry G
@bgits
Oct 07 2016 15:25
How can I get this to work with nested objects so that it returns an array of just values? In this case the desired output is: [1,2,3,5]. https://goo.gl/kPiKL5
Ryan Zeigler
@rzeigler
Oct 07 2016 15:26
i feel like somewhere there is a recipe for flattening nested keys, i.e. {‘a’: 1, {‘b’: {‘c’: 2}} => {‘a’: 1, ‘b.c’: 2}
Barry G
@bgits
Oct 07 2016 15:28
@rzeigler there is, but it requires writing a messy looking function first, wondering if there is a simpler pointfree way to do it?
Ryan Zeigler
@rzeigler
Oct 07 2016 15:28
hang on
working on it
function deepValues(obj) {
  return R.chain(R.cond([
    [R.is(Object), deepValues],
    [R.T, R.of]
  ]), R.values(obj))
}
Barry G
@bgits
Oct 07 2016 15:33
slick, just seems like so much more complexity over a simple values
Ryan Zeigler
@rzeigler
Oct 07 2016 15:33
i mean, you’ve got to accomodate for recursion
somehow
i’m not actually sure how that would handle nested arrays
i suspect weird things would happen
if you want to account for everything
function deepValues(obj) {
  return R.chain(R.cond([
    [R.is(Array), R.identity],
    [R.is(Object), deepValues],
    [R.T, R.of]
  ]), R.values(obj))
}
Ryan Zeigler
@rzeigler
Oct 07 2016 15:39
the array check probably isn’t necessary, but its probably faster since you can use the array directly instead of valuesing it first
Kurt Milam
@kurtmilam
Oct 07 2016 15:52

@jigargosar I think you're right. The confounding factor is that the actual code is recursive and looks more like this:

const complicatedFlatten  = converge(append,[ getMainValue, complicatedFlatten])

I can't call complicatedFlatten from within the assignment, so I'll need to fix that before I can switch to point-free style here.

Brad Compton (he/him)
@Bradcomp
Oct 07 2016 15:58
@kurtmilam In JavaScript you can't have point free recursive functions.
Well, to be more precise, you can't have self referential point free functions
Kurt Milam
@kurtmilam
Oct 07 2016 15:59
@Bradcomp In that case, I won't waste my time trying to figure out a solution - thanks for the useful tip!
I'll add that as a comment to the function declaration so I don't come back to it every couple of weeks and try to figure out why it's not point-free.
Brad Compton (he/him)
@Bradcomp
Oct 07 2016 16:02

heh. Sounds like a plan.

The self reference relies on the closure of a function body in order to work. In moving to point free, you are referencing the function at the same time it's being defined, so it ends up just being undefined.

Kurt Milam
@kurtmilam
Oct 07 2016 16:06
@Bradcomp That's exactly what was happening, and after I asked the question earlier today, I realized that I'd already figured out the converge() solution a couple weeks back (either on my own or with help - can't recall), but ran into the self-referential point-free function problem back then. Then I took a couple of weeks of vacation and forgot that I'd already been through the whole exercise. Comment has been added, and hopefully I'll remember the general rule, as well.
Thanks!