Как обобщить функцию с простой арифметикой?

https://play.rust-lang.org/?gist=2692daba1ad1183fd3c17cbcae0e9926

#[derive(Debug, Clone, Copy)]
struct A<T = i32>(T);

#[derive(Debug, Clone, Copy)]
struct B<T = i32>(T);

fn a2b_f(a: A<f32>) -> B<f32> {
    B(-a.0 - a.0)
}

fn a2b_i(a: A) -> B {
    B(-a.0 - a.0)
}

// что должно быть на месте '?', что бы слепить две функции выше в одну обобщенную?
// fn a2b<T: ?>(a: A<T>) -> B<T> {
//     B(-a.0 - a.0)
// }

fn main() {
    let i_a = A(1);
    let i_b = a2b_i(i_a);
    println!("{:?} -> {:?}", i_a, i_b);
    
    let f_a = A(1.0);
    let f_b = a2b_f(f_a);
    println!("{:?} -> {:?}", f_a, f_b);
}

T: Copy + Debug + ops::Neg + ops::Sub не сильно помогли

решение от @Albibek из гиттера:

fn a2b<T: Copy + ops::Neg<Output=T> + ops::Sub<Output=T>>(a: A<T>) -> B<T> {...}

@a1xt предложил использовать https://docs.rs/num для большей выразительности

1 лайк

std::ops::Sub<Output=T>+std::ops::Neg<Output=T>+Copy

Если не указать Output=T, то ругается

error[E0369]: binary operation `-` cannot be applied to type `<T as std::ops::Neg>::Output`
  --> <anon>:11:7
   |
11 |     B(-a.0 - a.0)
   |       ^^^^
   |
   = note: an implementation of `std::ops::Sub` might be missing for `<T as std::ops::Neg>::Output`

https://play.rust-lang.org/?gist=c5649ff3ea1355089c762f3eb270b34d

Кстати, я потыкался в https://docs.rs/num и не понял как он поможет упростить код выше, потому что https://docs.rs/num/0.1.39/num/trait.Num.html с виду не умеет в унарный минус и я хз как это выразить через то что есть. Не писать же 0 - a.0 - a.0?