0

I try to write generic method and specify some type T: num_traits::float::Float from num-traits crate. How should I ask &T to implement basic numeric methods such as multiplication?

use splines::{Interpolation, Key, Spline, interpolate};
use num_traits::{float::Float, identities};
use conv::prelude::*;


struct Interpolator<T>
where T: Float + interpolate::One + interpolate::Trigo {
    target_x: Vec<T>,
}

impl<T> Interpolator<T>
where T: Float + interpolate::One + interpolate::Trigo {
    fn interpolate<U>(&self, x: &[T], y: &[U]) -> Vec<U>
    where U: Float + identities::Zero {
        assert_eq!(x.len(), y.len());
        let key_iter = x.iter().zip(y).map(|(x, y)| Key::new(x, y, Interpolation::Linear));
        let spline = Spline::from_iter(key_iter);
        let result: Vec<U> = self.target_x.iter().map(|x| spline.sample(x).unwrap_or(identities::zero())).collect();
        result
    }
}


fn main() {
}

Cargo.toml

[package]
name = "name"
version = "0.1.0"
edition = "2018"

[dependencies]
conv = "0.3.2"
splines = "1.0.0-rc.3"
num-traits = "0.2"

Compilation errors:

error[E0277]: the trait bound `&T: splines::interpolate::One` is not satisfied
  --> src/main.rs:18:66
   |
18 |         let result: Vec<U> = self.target_x.iter().map(|x| spline.sample(x).unwrap_or(identities::zero())).collect();
   |                                                                  ^^^^^^ the trait `splines::interpolate::One` is not implemented for `&T`

error[E0277]: the trait bound `&T: splines::interpolate::Trigo` is not satisfied
  --> src/main.rs:18:66
   |
18 |         let result: Vec<U> = self.target_x.iter().map(|x| spline.sample(x).unwrap_or(identities::zero())).collect();
   |                                                                  ^^^^^^ the trait `splines::interpolate::Trigo` is not implemented for `&T`

error[E0277]: cannot multiply `&T` to `&T`
  --> src/main.rs:18:66
   |
18 |         let result: Vec<U> = self.target_x.iter().map(|x| spline.sample(x).unwrap_or(identities::zero())).collect();
   |                                                                  ^^^^^^ no implementation for `&T * &T`
   |
   = help: the trait `std::ops::Mul` is not implemented for `&T`
   = help: consider adding a `where &T: std::ops::Mul` bound

error[E0277]: cannot divide `&T` by `&T`
  --> src/main.rs:18:66
   |
18 |         let result: Vec<U> = self.target_x.iter().map(|x| spline.sample(x).unwrap_or(identities::zero())).collect();
   |                                                                  ^^^^^^ no implementation for `&T / &T`
   |
   = help: the trait `std::ops::Div` is not implemented for `&T`
   = help: consider adding a `where &T: std::ops::Div` bound

error[E0277]: the trait bound `&U: splines::interpolate::Interpolate<&T>` is not satisfied
  --> src/main.rs:18:66
   |
18 |         let result: Vec<U> = self.target_x.iter().map(|x| spline.sample(x).unwrap_or(identities::zero())).collect();
   |                                                                  ^^^^^^ the trait `splines::interpolate::Interpolate<&T>` is not implemented for `&U`

error[E0277]: cannot add `&T` to `&T`
  --> src/main.rs:18:66
   |
18 |         let result: Vec<U> = self.target_x.iter().map(|x| spline.sample(x).unwrap_or(identities::zero())).collect();
   |                                                                  ^^^^^^ no implementation for `&T + &T`
   |
   = help: the trait `std::ops::Add` is not implemented for `&T`
   = help: consider adding a `where &T: std::ops::Add` bound
   = note: required because of the requirements on the impl of `splines::interpolate::Additive` for `&T`

error[E0277]: cannot subtract `&T` from `&T`
  --> src/main.rs:18:66
   |
18 |         let result: Vec<U> = self.target_x.iter().map(|x| spline.sample(x).unwrap_or(identities::zero())).collect();
   |                                                                  ^^^^^^ no implementation for `&T - &T`
   |
   = help: the trait `std::ops::Sub` is not implemented for `&T`
   = help: consider adding a `where &T: std::ops::Sub` bound
   = note: required because of the requirements on the impl of `splines::interpolate::Additive` for `&T`

error[E0277]: the trait bound `&U: num_traits::identities::Zero` is not satisfied
  --> src/main.rs:18:86
   |
18 |         let result: Vec<U> = self.target_x.iter().map(|x| spline.sample(x).unwrap_or(identities::zero())).collect();
   |                                                                                      ^^^^^^^^^^^^^^^^ the trait `num_traits::identities::Zero` is not implemented for `&U`
   |
   = note: required by `num_traits::identities::zero`

error[E0277]: a collection of type `std::vec::Vec<U>` cannot be built from an iterator over elements of type `&U`
  --> src/main.rs:18:107
   |
18 |         let result: Vec<U> = self.target_x.iter().map(|x| spline.sample(x).unwrap_or(identities::zero())).collect();
   |                                                                                                           ^^^^^^^ a collection of type `std::vec::Vec<U>` cannot be built from `std::iter::Iterator<Item=&U>`
   |
   = help: the trait `std::iter::FromIterator<&U>` is not implemented for `std::vec::Vec<U>`

error: aborting due to 9 previous errors

For more information about this error, try `rustc --explain E0277`.
error: Could not compile `trait_generic`.
hombit
  • 131
  • 1
  • 9
  • Could you share a repo with a reproducable example, and the actual full error message? – Some Guy Jun 25 '19 at 09:53
  • Related: https://stackoverflow.com/questions/29184358/how-do-i-require-a-generic-type-implement-an-operation-like-add-sub-mul-or-di, https://stackoverflow.com/questions/37296351/trait-for-numeric-functionality-in-rust, – Peter Hall Jun 25 '19 at 10:24
  • If I just had to guess based on the error, maybe you just need `spline.sample(*x)`, but I don't see why from just the code you've posted. Something we can compile ourselves would help :) – Some Guy Jun 25 '19 at 10:55
  • Updated with full example and error – hombit Jun 25 '19 at 12:16

1 Answers1

1

Maybe you could just consider using Key::new(*x, *y, Interpolation::Linear) and spline.sample(*x)?

0x2207
  • 878
  • 1
  • 6
  • 20