Я пытаюсь реализовать классический высокий диапазон порядка zipWith
следующимПопытка реализовать zipWith
import std.traits: allSatisfy;
import std.range: isInputRange;
auto zipWith(fun, Ranges...)(Ranges ranges) if (Ranges.length >= 2 && allSatisfy!(isInputRange, Ranges))
{
import std.range: zip;
return zip(ranges).map!fun;
}
но
unittest
{
auto x = [1, 2, 3, 4, 5];
zipWith!((a, b) => a + b)(x, x);
}
с ошибкой
template algorithm_ex.zipWith cannot deduce function from argument types !((a, b) => a + b)(int[], int[]), candidates are: (d-dmd-unittest)
algorithm_ex.zipWith(fun, Ranges...)(Ranges ranges) if (Ranges.length && allSatisfy!(isInputRange, Ranges))
и я дон Не понимаю почему. Кто-нибудь подсказывает?
Update:
После CyberShadows хороший ответ теперь у меня есть
import std.traits: allSatisfy;
/** Zip $(D ranges) together with operation $(D fun).
TODO: Simplify when Issue 8715 is fixed providing zipWith
*/
auto zipWith(alias fun, Ranges...)(Ranges ranges) if (Ranges.length >= 2 && allSatisfy!(isInputRange, Ranges)) {
import std.range: zip;
import std.algorithm: map;
import std.functional: binaryFun;
static if (ranges.length == 2)
return zip(ranges).map!(a => binaryFun!fun(a.expand));
else if (ranges.length >= 3)
return zip(ranges).map!(a => naryFun(a.expand));
else
static assert(false, "Need at least 2 range arguments.");
}
unittest {
auto x = [1, 2, 3];
import std.array: array;
assert(zipWith!"a+b"(x, x).array == [2, 4, 6]);
assert(zipWith!((a, b) => a + b)(x, x).array == [2, 4, 6]);
assert(zipWith!"a+b+c"(x, x, x).array == [3, 6, 9]);
}
Можно ли расширить его поддержку ни капли веселья с помощью строк, как zipWith!"a+b+c"(x,x,x)
? Я спрашиваю, особенно, потому что я замечаю, что есть код для naryFun
в std.functional, но он закомментирован.
Пожалуйста, смотрите обновления выше относительно 'naryFunction'. –
Обновленный ответ. –
Возможно, вы также захотите, чтобы naryFun возвращал нечто, отличное от int. авто приходит на ум. :п – BioTronic