To me, aggregate
is implemented with slightly the wrong abstraction.
I hope someone can correct me if I misunderstand something here.
But aggregate
takes two functions
seqop: (B, A) ⇒ B
and combop: (B, B) ⇒ B
whereas it should take
unaryop:A=>B
and combop: (B, B) ⇒ B
and then should internally compute seqop
as
(b:B,a:A)=>combop(b,unaryop(a))
.
I believe it makes the assumption that the user’s given combop
contains the same code as combop
, but doesn’t have anyway to verify that invariant.
Perhaps (I’m guessing) it is (was) defined as it is/was, because unaryop
is very often the identity function, and letting the user specify seqop
allows a call to the identity function to be optimized away.