On Saturday, 5 July 2014 at 19:31:24 UTC, Marc Schütz wrote:
This is an instance of these bugs:

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

But seeing that `map` works with a single lambda/local function, it should be possible to make it work with several ones too.

For the time being, a simple workaround is to make the local functions static:

This problem was introduced when std.algorithm.map was made to refuse void functions. But map already did fail void when it gets multiple functions, because std.typecons.tuple refuses variables of type void (though the error message is cryptic, sure):

"Error: variable std.typecons.Tuple!void.Tuple._expand_field_0 variables cannot be of type void"

The only thing map didn't fail was single argument void. This was fixed, so why not re-use the same fix for multiple arguments? The example below works fine, and gives the new and sensible-er error message:


template map(fun...) if (fun.length >= 1)
{
    auto map(Range)(Range r) if (isInputRange!(Unqual!Range))
    {
        alias AppliedReturnType(alias f) = typeof(f(r.front));

        static if (fun.length > 1)
        {
            import std.functional : adjoin;

            import std.typetuple : staticIndexOf;

            alias _funs = staticMap!(unaryFun, fun);
            alias _fun = adjoin!_funs;

// Attack of the copy-paste and poorly chosen variable name:
            foreach(_f; _funs){
                static assert(!is(AppliedReturnType!_f == void),
"All mapping functions must not return void.");
            }
        }
        else
        {
            alias _fun = unaryFun!fun;

            static assert(!is(AppliedReturnType!_fun == void),
"Mapping function must not return void.");

        }

        return MapResult!(_fun, Range)(r);
    }
}


Am I missing something?

Reply via email to