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.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…