Generic Sum Impl


#1

Hey, I was wondering why we don’t have something like this (from looking at the docs for std::iter::Sum):

impl<T> Sum<T> for T where T: Add<T>

I would have thought such a thing should be straightforward to implement, and powerful!


#2

You also need a zero.


#3

Gah, fair point. I suppose that Sum could in theory make use of some Zero trait to do this (and have impl<T> Sum for T where T: Add + Zero), but by that point it’s hardly more work to type out an impl for Sum.


#4

You can “fake” a zero with Default but that’s bending things a bit and may yield incorrect results for some types.


#5

Agreed, I don’t think Default should be reliably interpreted as a zero!


#6

So Default hacks aside, most people use the num crate for this: http://rust-num.github.io/num/num/index.html. It defines a Zero trait, amongst other things.


#7

Iterator::Sum has been through a few different bounds; if you look in the past you’ll find (never-stabilized) things like https://doc.rust-lang.org/1.9.0/std/num/trait.Zero.html

One could also do something like

use std::ops::Add;
fn sum1<T:Add<Output=T>,I:Iterator<Item=T>>(mut it: I) -> Option<T> {
    if let Some(init) = it.next() {
        Some(it.fold(init, Add::add))
    } else {
        None
    }
}

#8

I think a one liner like it.next().map(|x| it.fold(x, Add::add)) would work as well.