## digitalmars.D - A Recurring Question

• w0rp (34/34) Apr 17 2016 I recently found myself wanting an algorithm to apply f(x)
• thedeemon (9/16) Apr 18 2016 It really looks like "iterate" combinator from Haskell's standard
• w0rp (3/19) Apr 18 2016 If it's good enough for Haskell, maybe it's good enough for us.
• Jesse Phillips (10/18) Apr 18 2016 FYI, OS independent version:
• w0rp (2/21) Apr 18 2016 Nice!
w0rp <devw0rp gmail.com> writes:
```I recently found myself wanting an algorithm to apply f(x)
repeatedly, generating an infinite sequence, for a variety of
reasons. One of those reasons is to generate ancestor
directories. Typically when I desire such a thing, I find myself
trying to find the existing algorithm which does this already. I
eventually realised that recurrence is exactly what I need, if I
just simplify it a little for this case.

import std.range;
import std.algorithm;
import std.path;
import std.file;
import std.stdio;

auto unaryRecurrence(alias func, T)(T initialValue) {
return recurrence!((values, index) =>
func(values[0]))(initialValue);
}

void main() {
// Print all directories from this one up to and including /.
getcwd()
.unaryRecurrence!dirName
.until("/", OpenRight.no)
.each!writeln;
}

This is kind of neat. My question is, should something like this
function be included in std.range? Either way, it turned into an
example of something cool you can do with D.

While I was at it, I noticed that we could also consider a second
form of recurrence which permits functions which accept a single
argument, with only the Cycle. In that case, the range behind the
recurrence could be potentially optimised to only hold the
values, and forget about the index. It wouldn't be too far off
from how foreach works. Then my function above would have had

x => func(x[0])
```
Apr 17 2016
thedeemon <dlang thedeemon.com> writes:
```On Sunday, 17 April 2016 at 15:23:50 UTC, w0rp wrote:
auto unaryRecurrence(alias func, T)(T initialValue) {
return recurrence!((values, index) =>
func(values[0]))(initialValue);
}

This is kind of neat. My question is, should something like
this function be included in std.range? Either way, it turned
into an example of something cool you can do with D.

It really looks like "iterate" combinator from Haskell's standard
library:

iterate :: (a -> a) -> a -> [a] Source

iterate f x returns an infinite list of repeated applications of
f to x:
iterate f x == [x, f x, f (f x), ...]

(which could be a hint to stdlib-includability and naming)
```
Apr 18 2016
w0rp <devw0rp gmail.com> writes:
```On Monday, 18 April 2016 at 12:02:24 UTC, thedeemon wrote:
On Sunday, 17 April 2016 at 15:23:50 UTC, w0rp wrote:
auto unaryRecurrence(alias func, T)(T initialValue) {
return recurrence!((values, index) =>
func(values[0]))(initialValue);
}

This is kind of neat. My question is, should something like
this function be included in std.range? Either way, it turned
into an example of something cool you can do with D.

It really looks like "iterate" combinator from Haskell's
standard library:

iterate :: (a -> a) -> a -> [a] Source

iterate f x returns an infinite list of repeated applications
of f to x:
iterate f x == [x, f x, f (f x), ...]

(which could be a hint to stdlib-includability and naming)

If it's good enough for Haskell, maybe it's good enough for us.
"iterate" does sound like a decent name.
```
Apr 18 2016
Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
```On Sunday, 17 April 2016 at 15:23:50 UTC, w0rp wrote:
void main() {
// Print all directories from this one up to and including
/.
getcwd()
.unaryRecurrence!dirName
.until("/", OpenRight.no)
.each!writeln;
}

FYI, OS independent version:

void main() {
// Print all directories from this one up to and including /.
getcwd()
.unaryRecurrence!dirName
.until(rootName(getcwd()), OpenRight.no)
.each!writeln;
}

Probably should also make a call to absolutePath.
```
Apr 18 2016
w0rp <devw0rp gmail.com> writes:
```On Monday, 18 April 2016 at 20:24:40 UTC, Jesse Phillips wrote:
On Sunday, 17 April 2016 at 15:23:50 UTC, w0rp wrote:
void main() {
// Print all directories from this one up to and including
/.
getcwd()
.unaryRecurrence!dirName
.until("/", OpenRight.no)
.each!writeln;
}

FYI, OS independent version:

void main() {
// Print all directories from this one up to and including
/.
getcwd()
.unaryRecurrence!dirName
.until(rootName(getcwd()), OpenRight.no)
.each!writeln;
}

Probably should also make a call to absolutePath.

Nice!
```
Apr 18 2016