I'm trying to write some generic math functions in Rust and I keep running into the following error message:
error: conflicting implementations for trait SoAndSo Is it possible to solve the problem? If so, how?
For example, I'm trying to write a generic dot product that takes two iterators, zips them and iterates over the pairs to accumulate the products. I want this function also to be able to compute complex-valued dot products. The dot product over complex numbers involves conjugating one side. My first idea was to write a trait Dot1 for a binary function to replace Mul in that it also conjugates the left hand side argument. Here's the complete code:
extern crate num; use num::complex::Complex; use num::{Float, Num}; trait Dot1<Rhs, Result> { fn dot1(&self, rhs: Rhs) -> Result; } impl<T: Float> Dot1<T, T> for T { // conjugation for reals is a no-op fn dot1(&self, rhs: T) -> T { *self * rhs } } impl<T: Num + Clone> Dot1<Complex<T>, Complex<T>> for Complex<T> { fn dot1(&self, rhs: Complex<T>) -> Complex<T> { self.conj() * rhs } } fn main() { println!("Hello, world!") } Since a Complex<T> is not Float, there should be no overlap between the two "generic impls". I didn't expect any problems, but every time I try to provide more than one "generic impl" for a trait, the compiler doesn't like it:
error[E0119]: conflicting implementations of trait `Dot1<num::Complex<_>, num::Complex<_>>` for type `num::Complex<_>`: --> src/main.rs:17:1 | 10 | impl<T: Float> Dot1<T, T> for T { | ------------------------------- first implementation here ... 17 | impl<T: Num + Clone> Dot1<Complex<T>, Complex<T>> for Complex<T> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `num::Complex<_>` | = note: upstream crates may add new impl of trait `num::Float` for type `num::Complex<_>` in future versions How can I write a generic, iterator-based dot product that works for both real and complex numbers? Taking the iterators, zipping them, etc. is not a problem and I was even able to figure out what type parameters to use with which bounds. I don't seem able to "unify" certain data types using traits such as the one from above.