On Sun, Jun 27, 2010 at 08:07, BCS <none@anon.com> wrote:
Hello Jonathan,


For example, there are two functions that I'd like to be have: all()
and any(). That is, I want a function which checks a predicate against
a range and returns whether all elements in that range satisfy the
predicate, and I want a function that checks a predicate against a
range and returns whether any element satisfies the predicate.
Ideally, all() would shortcut if it found even one element which
didn't satisfy the predicate, and any() would shortcut if it found
even one that did.

The trivial solution (no shortcuting) would be to map the predicate and reduce via 'and' or 'or'.

Or do a new version of reduce that stops the reducing on a certain condition

reduceWhile(alias reducer, alias predicate) {... reduce using reducer, as long as predicate holds }

That would be a nice addition to std.algo. The question is: what should test the predicate? The last returned value, the entire result being created?



As an asideJonathan, you may be interested in using some of the algorithms here:

http://www.dsource.org/projects/dranges

'all' and 'some' are in the 'predicates' module. They accept predicates of any arity (even 0!), because I wanted to test for increasing numerical ranges, like this :

auto isGrowing = all ! "a<b" (range);

Note that the fact of accepting variable-arity predicates represents 90% of the complexity, because a simple all is:

import std.functional: unaryFun;
import std.range: isInputRange;

bool all(alias predicate, R)(R range) if (isInputRange!R)
{
    foreach(elem; range)
    {
        if (!unaryFun!predicate(elem)) return false;
    }
    return true;
}
// warning : untested.

usage:

auto a = all ! "a<0" (range)

or

auto a = all ! foo (range)


Philippe