I'd like to have an object that takes a vector of items of a generic type D (say, D: Vec<64>
) and performs some generic mathematical operation on them, e.g. finds the two closest elements of this vector given some generic metric M. The ability to compute that distance is declared by Distance<D>
trait where D
is the type of data being compared. Then I implemented that trait for a ManhattanDistance
and now I'd like my struct ClosestPair<M>
find the two closest points with ManhattanDistance
serving as M
.
I'd also like the very same ClosestPair<M>
to work with String
data and some Distance<String>
. But rust says:
Compiling playground v0.0.1 (/playground)
error[E0207]: the type parameter `D` is not constrained by the impl trait, self type, or predicates
--> src/main.rs:24:6
|
24 | impl<D: Index<usize>, M> ClosestPair<M> {
| ^ unconstrained type parameter
Here is my attempt:
use core::ops::Index;
pub trait Distance<D> {
fn d(di:&D, dj:&D) -> D;
}
struct ManhattanDistance {}
impl Distance<Vec<f64>> for ManhattanDistance {
fn d(di: &Vec<f64>, dj: &Vec<f64>) -> f64 {
let mut out:f64 = 0.0;
for i in 0..di.len() {
out += (di[i]-dj[i]).abs();
}
return out;
}
}
struct ClosestPair<M> {
measure: M
}
impl<D: Index<usize>, M> ClosestPair<M> {
pub fn find_closest(&self, data: Vec<D>) -> f64{
self.measure.d(&data[0], &data[1])
}
}
pub fn main() {
let p1: Vec<f64> = vec![0.0, 1.0, 2.0];
let p2: Vec<f64> = vec![4.0, 1.0, 2.0];
let p3: Vec<f64> = vec![0.0, 2.0, 2.0];
let data = vec![p1, p2, p3];
let closest: ClosestPair<ManhattanDistance>;
closest.find_closest(data);
}