reduce -> fold?

Atila Neves via Digitalmars-d digitalmars-d at puremagic.com
Thu Feb 4 01:38:25 PST 2016


On Wednesday, 3 February 2016 at 21:45:04 UTC, Timon Gehr wrote:
> On 02/03/2016 09:12 PM, Atila Neves wrote:
>>
>> https://github.com/D-Programming-Language/phobos/pull/3968
>>
>> I think fold should be nothrow, but maybe that's just me. It's 
>> also a
>> massive pain to make it that way, so I didn't for now.
>
> Returning Unqual!(ElementType!R).init makes no sense though.
> The "correct" result of fold!f([]) is a (often, the) value 'a' 
> such that for any 'b', 'f(a,b)==b' (which is the canonical 
> choice of "seed"), but there is no way for fold to infer such a 
> value.

Right. I wrote in a hurry and without checking the code I'd 
written yesterday. The correct value to return for one function 
would be:

template fold(fun...) {
     alias binFuncs = staticMap!(binaryFun, fun);
     // checks for fun.length == 1, etc.
     auto fold(R)(R r) {
         return Unqual!(typeof(binFuncs[0](r.front, 
r.front))).init;
     }
}

Since there's no seed, the first element of the range would 
normally be used. But the fact that the range is empty doesn't 
change what type such a first element would have. The element 
type of the range is fixed (i.e. the 2nd element would be the 
same type as the 1st), so passing front twice to the binary 
function means the types check out.

For multiple functions it gets hairy fast, but basically 
generalise the above to a tuple with the same expression but 
instead of always using binFuncs[0] it uses all of them. I've got 
an implementation that works, as long as the functions passed in 
aren't local. Seems to be some staticMap limitation or maybe I'm 
just doing it wrong.

Atila



More information about the Digitalmars-d mailing list