These are chat archives for ramda/ramda

27th
Feb 2016
Andy Steinberg
@HolyMeekrob
Feb 27 2016 01:07
Is there a function in Ramda that would allow me to do something similar to Haskell's iterate function?
Scott Sauyet
@CrossEye
Feb 27 2016 01:45
@HolyMeekrob: Ramda doesn't really do anything with lazy lists, so I don't see an easy way to implement something like that. We certainly don't have anything like that.
Andy Steinberg
@HolyMeekrob
Feb 27 2016 01:50
Yeah, it would probably require returning an iterator. Some ideas I had that might work would be iterateN (essentially doing take n iterate), iterateUntil, which would take a (a -> bool) function and stop iterating once it's true, or iterateWhile, which would be the same thing only with that function complemented
Scott Sauyet
@CrossEye
Feb 27 2016 01:51
We had a lazy list extension for a while, but we weren't putting any effort towards it and we pulled it out as mostly a distraction. I think it might be worth resurrecting one day.
Andy Steinberg
@HolyMeekrob
Feb 27 2016 01:53
That could be useful. Thanks for the reply. I looked through the docs and didn't see anything, so I wanted to check.
Scott Sauyet
@CrossEye
Feb 27 2016 02:05
@HolyMeekrob: Not a completely satisfying answer, but using into and take to limit the iteration, you could write something like this:
const iterate = curry((fn, a) => ({
  [Symbol.iterator] () {
    let val = a, next = a;
    return {
      next: () => {
        [next, val] = [fn(next), next];
        return {done: false, value: val};
      }
    }
  }
}))

into([], take(5), iterate(n => n * n, 2));
//=> [2, 4, 16, 256, 65536]
Andy Steinberg
@HolyMeekrob
Feb 27 2016 02:53
@CrossEye That's pretty clever. I hadn't seen into.
Hardy Jones
@joneshf
Feb 27 2016 02:56
@ram-bot
const iterate = (f, x) => R.unfold(y => f(y) ? [f(y), f(y)] : false, x);
iterate(R.ifElse(R.gt(10), R.inc, R.always(false)));
ram-bot
@ram-bot
Feb 27 2016 02:56
[]
Hardy Jones
@joneshf
Feb 27 2016 02:56
hrm...
@ram-bot
const iterate = (f, x) => R.unfold(y => f(y) ? [f(y), f(y)] : false, x);
iterate(R.ifElse(R.gt(10), R.inc, R.always(false)), 3);
ram-bot
@ram-bot
Feb 27 2016 02:57
[ 4, 5, 6, 7, 8, 9, 10 ]
Hardy Jones
@joneshf
Feb 27 2016 02:57
there
Scott Sauyet
@CrossEye
Feb 27 2016 02:57
I forgot we still had unfold. Thought we lost that with the lazy lists!
Hardy Jones
@joneshf
Feb 27 2016 02:59
@ram-bot
const iterateN = (f, n, x) => R.unfold(o => o.count >= n ? false : [f(o.x), {count: o.count + 1, x: f(o.x)}], {count: 0, x});
iterateN(R.dec, 12, 35)
ram-bot
@ram-bot
Feb 27 2016 02:59
[ 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23 ]
Hardy Jones
@joneshf
Feb 27 2016 02:59
obviously, don't actually inline those
@CrossEye I'm glad it's still there :)
Scott Sauyet
@CrossEye
Feb 27 2016 02:59
yes!
Hardy Jones
@joneshf
Feb 27 2016 03:01
Hmm, I guess that first one isn't entirely right
nor that second one
It should be y and o.x as the first element in the array
respectively
since:
λ: take 10 $ iterate (+ 1) 3
[3,4,5,6,7,8,9,10,11,12]
Or I guess, more closely:
λ: takeWhile  (< 10) $ iterate (+ 1) 3
[3,4,5,6,7,8,9]
Why do those two blocks have different highlighting?
Scott Sauyet
@CrossEye
Feb 27 2016 03:04
no clue
Andy Steinberg
@HolyMeekrob
Feb 27 2016 03:13
@joneshf Very cool. I guess this is how you'd avoid breaking on falsy values like 0. Still breaks if you were making a list of booleans...
const iterate = (f, x) => R.unfold(y => f(y) !== false ? [y, f(y)] : false, x);
Andy Steinberg
@HolyMeekrob
Feb 27 2016 03:23
@ram-bot
const iterateWhile = (fIter, fValidate, x) => R.unfold(y => fValidate(y) ? [y, fIter(y)] : false, x);
iterateWhile(R.inc, R.gt(10), -3);
ram-bot
@ram-bot
Feb 27 2016 03:23
[ -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
Hardy Jones
@joneshf
Feb 27 2016 03:52
There you go!
Maybe sanctuary could provide a more robust solution?
@davidchambers thoughts ?
Oh, it has unfoldr!
David Chambers
@davidchambers
Feb 27 2016 03:54
Yep!
@benperez added that one because he wasn't happy with the signature of R.unfold.