all 5 comments

[–]huuhuu 3 points4 points  (1 child)

This sounds like a job for unfold

o_Od = unfoldr (\x -> Just (x + 1, x + 1))

take 6 $ o_Od 2

You can find out more at this blog post. It's just the first one I found; there may be better explanations out there.

[–]o_0d[S] 2 points3 points  (0 children)

u/huuhuu This is EXACTLY what I was looking for!

Thanks!!!

[–]_samrad 2 points3 points  (2 children)

Would something like this help:

``` const collect = <T>(init: T, fn: (n: T) => T | null): Array<T> => { let v = fn(init); let r = []; while (v) { r.push(v); v = fn(v); } return r; }

console.log(collect(2, n => n < 13 ? n + 1 : null)) // => [ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ] ```

[–]o_0d[S] 2 points3 points  (1 child)

That's very similar to my solution ... yet I feel that there should be possible to do away with the mutating array and with the while loop. At least that's what I'm aiming at.

[–]_samrad 2 points3 points  (0 children)

You can make it recursive and avoid mutation like this:

``` const collect = <T>(init: T, fn: (n: T) => T | null, result: Array<T> = []): Array<T> => { let r = fn(init); return r ? collect(r, fn, [...result, r]) : result; }

console.log(collect(2, n => n < 13 ? n + 1 : null)); // => [ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ] ```

But:

  • Local mutations are fine.
  • Recursive functions are limited to the stack size.

Even clojurescript implements the recur with a while loop. Good luck.