I'm trying to write the PartialEq trait for a struct and emits this error:
conflicting implementations of trait `PartialEq` for type `Matrix<_, _>`
where there are two different implementations (at least with alternated const generics):
impl<const M: usize, const N: usize> PartialEq for Matrix<M, N>
where
[f64; M * N]:,
{ ... }
impl<const M: usize, const N: usize> PartialEq<Matrix<N, M>> for Matrix<M, N>
where
[f64; N * M]:,
[f64; M * N]:,
{ ... }
My solution on this is trying to tell to the compiler that in some scenarios if M == N then M is N and can be also "partialequalized" with a Matrix<N, M>:
/// &self as Matrix<M, N>
pub fn reverse_types(&self) -> Option<Matrix<N, M>>
where
[f64; M * N]:,
[f64; N * M]:,
{
if !self.is_square() {
return None;
}
let mut data: [f64; N * M] = [0.; N * M];
data.par_iter_mut()
.enumerate()
.for_each(|(idx, el)| *el = self.data[idx]);
Some(Matrix {
rows: N,
cols: M,
data,
})
}
But i don't like this runtime solution when all the checks are at compile time.
The target use case is this:
/// &self as Matrix<M, N>
pub fn is_symmetric(&self) -> bool
where
[f64; N * M]:,
{
if !self.is_square() {
return false;
}
/// self.transpose() as Matrix<N, M>
let Some(transposed) = self.transpose().reverse_types() else {
return false;
};
*self == transposed
}