I am trying to design a pair of traits (e.g. RowVector and ColumnVector from linear algebra) where each trait returns the other from one of its methods (e.g. transpose). I want to be able to add implementations of either trait in the future (such as dense and sparse vector implementations).
#[macro_use]
extern crate derive_new;
trait RowVector<Element> {
fn transpose(self) -> ColumnVector<Element>;
}
trait ColumnVector<Element> {
fn transpose(self) -> RowVector<Element>;
}
#[derive(new, Debug)]
struct VecRowVector<Element> {
vec: Vec<Element>
}
#[derive(new, Debug)]
struct VecColumnVector<Element> {
vec: Vec<Element>
}
impl<Element> RowVector<Element> for VecRowVector<Element> {
fn transpose(self) -> VecColumnVector<Element> {
VecColumnVector::new(self.vec)
}
}
impl<Element> ColumnVector<Element> for VecColumnVector<Element> {
fn transpose(self) -> VecRowVector<Element> {
VecRowVector::new(self.vec)
}
}
fn main() {
let row_vector = VecRowVector::new(vec![1,2,3]);
let col_vector = VecColumnVector::new(vec![1,2,3]);
println!("{:?}", row_vector.transpose());
println!("{:?}", col_vector.transpose());
}
I get an error saying that VecColumnVector is not a ColumnVector and it's expecting a 'static value.
error[E0053]: method `transpose` has an incompatible type for trait
--> src\main.rs:22:31
|
4 | fn transpose(self) -> ColumnVector<Element>;
| --------------------- type in trait
...
22 | fn transpose(self) -> VecColumnVector<Element> {
| ^^^^^^^^^^^^^^^^^^^^^^^^ expected trait ColumnVector, found struct `VecColumnVector`
|
= note: expected type `fn(VecRowVector<Element>) -> ColumnVector<Element> + 'static`
= note: found type `fn(VecRowVector<Element>) -> VecColumnVector<Element>`
Have I not made VecColumnVector a subtype of ColumnVector? Or do I somehow need to tell the trait that it doesn't need to be a static lifetime?