Advertisement
Kyosuta

rust - trait implementation problems

May 19th, 2018
234
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 4.51 KB | None | 0 0
  1. use std::ops::Mul;
  2.  
  3. // definition of vector type
  4.  
  5. #[derive(Debug, Clone, PartialEq)]
  6. pub struct Vector<T>
  7.     where T: Clone + Copy {
  8.     value: Vec<T>
  9. }
  10.  
  11. // these two Mul implementations are fine
  12. // they take owned values
  13.  
  14. impl<T, U, O> Mul<Vector<U>> for Vector<T>
  15.     where T: Clone + Copy + Mul<U, Output = O>,
  16.           U: Clone + Copy,
  17.           O: Clone + Copy {
  18.     type Output = Result<Vector<O>, String>;
  19.  
  20.     fn mul(self, rhs: Vector<U>) -> Self::Output {
  21.         apply(self, rhs, |t, u| t * u)
  22.     }
  23. }
  24.  
  25. impl<T, U, O> Mul<U> for Vector<T>
  26.     where T: Clone + Copy + Mul<U, Output = O>,
  27.           U: Clone + Copy,
  28.           O: Clone + Copy {
  29.     type Output = Vector<O>;
  30.  
  31.     fn mul(self, rhs: U) -> Self::Output {
  32.         apply_const(self, |t| t * rhs)
  33.     }
  34. }
  35.  
  36. // these two Mul implementations don't work with each other
  37. // they take borrow values
  38. // if I comment one out the other works fine
  39. // This is the second major iteration of this code (the first is below)
  40.  
  41. impl<'a, 'b, T, U, O> Mul<&'b Vector<U>> for &'a Vector<T>
  42.     where T: Clone + Copy + Mul<U, Output = O>,
  43.           U: Clone + Copy,
  44.           O: Clone + Copy {
  45.     type Output = Result<Vector<O>, String>;
  46.  
  47.     fn mul(self, rhs: &'b Vector<U>) -> Self::Output {
  48.        apply_ref(self, rhs, |t, u| *t * *u)
  49.    }
  50. }
  51.  
  52. impl<'a, T, U, O> Mul<U> for &'a Vector<T>
  53.    where T: Clone + Copy + Mul<U, Output = O>,
  54.          U: Clone + Copy,
  55.          O: Clone + Copy {
  56.    type Output = Vector<O>;
  57.  
  58.    fn mul(self, rhs: U) -> Self::Output {
  59.        apply_const_ref(self, |t| *t * rhs)
  60.    }
  61. }
  62.  
  63. // This is what I had before I changed (I wanted to generalize the basic operations if type T could multiply with other types)
  64. // This led to the above code
  65. // This code works fine if swapped with the more general code above
  66. /*
  67. impl<'a, 'b, T> Mul<&'b Vector<T>> for &'a Vector<T>
  68.    where T: Clone + Copy + Mul<T, Output = T> {
  69.    type Output = Result<Vector<T>, String>;
  70.  
  71.    fn mul(self, rhs: &'b Vector<T>) -> Self::Output {
  72.         apply_ref(self, rhs, |t, u| *t * *u)
  73.     }
  74. }
  75.  
  76. impl<'a, T> Mul<T> for &'a Vector<T>
  77.     where T: Clone + Copy + Mul<T, Output = T> {
  78.     type Output = Vector<T>;
  79.  
  80.     fn mul(self, rhs: T) -> Self::Output {
  81.         apply_const_ref(self, |t| *t * rhs)
  82.     }
  83. }
  84. */
  85.  
  86. // These functions below are used more in the actual lib
  87. // so that I don't copy and paste code too much
  88. // ideally all of these functions would be consolidated
  89. // but I don't know how to generalize over both owned types
  90. // and borrow types at once
  91. // All of them take in a vector and the rhs of the operation (vector or scalar)
  92. // and a function, then it applies the function to the two inputs and stores into
  93. // a return value
  94. // these also perform dimension checks
  95.  
  96. impl<T> Vector<T>
  97. where T: Clone + Copy {
  98.     fn dim(&self) -> usize {
  99.         self.value.len()
  100.     }
  101. }
  102.  
  103. impl<T> From<Vec<T>> for Vector<T>
  104. where T: Clone + Copy {
  105.     fn from(value: Vec<T>) -> Self {
  106.         Self { value }
  107.     }
  108. }
  109.  
  110. fn apply<T, U, O, F>(t: Vector<T>, u: Vector<U>, f: F) -> Result<Vector<O>, String>
  111.     where T: Clone + Copy,
  112.           U: Clone + Copy,
  113.           O: Clone + Copy,
  114.           F: Fn(T, U) -> O {
  115.     if t.dim() != u.dim() {
  116.         return Err(format!("incompatible sizes"))
  117.     }
  118.  
  119.     let mut vec = Vec::with_capacity(t.dim());
  120.  
  121.     for (i, j) in t.value.iter().zip(u.value.iter()) {
  122.         vec.push(f(*i, *j))
  123.     }
  124.  
  125.     Ok(Vector::from(vec))
  126. }
  127.  
  128. fn apply_ref<'a, 'b, T, U, O, F>(t: &'a Vector<T>, u: &'b Vector<U>, f: F) -> Result<Vector<O>, String>
  129.     where T: Clone + Copy,
  130.           U: Clone + Copy,
  131.           O: Clone + Copy,
  132.           F: Fn(&'a T, &'b U) -> O {
  133.     if t.dim() != u.dim() {
  134.         return Err(format!("incompatible sizes"))
  135.     }
  136.  
  137.     let mut vec = Vec::with_capacity(t.dim());
  138.  
  139.     for (i, j) in t.value.iter().zip(u.value.iter()) {
  140.         vec.push(f(i, j))
  141.     }
  142.  
  143.     Ok(Vector::from(vec))
  144. }
  145.  
  146. fn apply_const<T, O, F>(t: Vector<T>, f: F) -> Vector<O>
  147.     where T: Clone + Copy,
  148.           O: Clone + Copy,
  149.           F: Fn(T) -> O {
  150.     let mut vec = Vec::with_capacity(t.dim());
  151.  
  152.     for i in t.value.iter() {
  153.         vec.push(f(*i));
  154.     }
  155.  
  156.     Vector::from(vec)
  157. }
  158.  
  159. fn apply_const_ref<'a, T, O, F>(t: &'a Vector<T>, f: F) -> Vector<O>
  160.     where T: Clone + Copy,
  161.           O: Clone + Copy,
  162.           F: Fn(&'a T) -> O {
  163.    let mut vec = Vec::with_capacity(t.dim());
  164.  
  165.    for i in t.value.iter() {
  166.        vec.push(f(i));
  167.    }
  168.  
  169.    Vector::from(vec)
  170. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement