[Issue 5510] std.functional.iterate

via Digitalmars-d-bugs digitalmars-d-bugs at puremagic.com
Sun Sep 14 05:08:45 PDT 2014


https://issues.dlang.org/show_bug.cgi?id=5510

--- Comment #2 from bearophile_hugs at eml.cc ---
"iterate" can act like the Haskell iterate, that yields all the intermediate
values.

This is a basic implementation plus an usage example with the Hailstone
sequence:



import std.stdio, std.typecons, std.traits, std.typetuple,
       std.range, std.algorithm;

auto iterate(alias F, T)(T x)
if (isCallable!F &&
    is(ParameterTypeTuple!F == TypeTuple!T) &&
    is(ReturnType!F == T)) {

    struct Iterate {
        T front;
        enum bool empty = false;
        void popFront() pure nothrow @safe @nogc { front = F(front); }
    }
    return Iterate(x);
}

// http://en.wikipedia.org/wiki/Collatz_conjecture
uint hailstone(uint n) pure nothrow @safe @nogc {
    if (n == 1)
        return 1;
    return (n & 1) ? (n * 3 + 1) : (n / 2);
}

void main() {
    enum uint start = 10;

    start
    .iterate!hailstone
    .until(1, OpenRight.no)
    .writeln;

    start
    .recurrence!((a, n) => hailstone(a[n - 1]))
    .until(1, OpenRight.no)
    .writeln;
}


Output:

[10, 5, 16, 8, 4, 2, 1]
[10, 5, 16, 8, 4, 2, 1]


An "iterate" can be implemented with a "recurrence", but iterate looks cleaner
for such simple but common cases.

--


More information about the Digitalmars-d-bugs mailing list