I have the following Trait implementation and would like to make unit
generic over Array1<T>
, but fail to find the right Trait bounds (especially that this somehow seems trivial to me, all T needs to support is basically basic arithmetic that output T for the function to work).
trait Unit {
fn unit(&self) -> Array1<f32>;
}
impl Unit for Array1<f32>
{
fn unit(&self) -> Array1<f32> {
self / (self * self).sum().sqrt()
}
}
The compiler suggests adding std::ops::Mul<Output = &ArrayBase<OwnedRepr<T>, Dim<[usize; 1]>>>
, but doing so keeps giving the same error over and over.
CodePudding user response:
I followed the compiler error messages and produced this generic code that compiles. I'm not familiar with ndarray
so I don't know if this is actually correct.
use std::ops::Mul;
use num_traits::{Zero, real::Real};
use ndarray::prelude::*;
trait Unit {
type Output;
fn unit(&self) -> Array1<Self::Output>;
}
impl<T> Unit for Array1<T>
where
for<'a> &'a Array1<T>: Mul<Output = Array1<T>>,
T: Real Clone Zero ndarray::ScalarOperand,
{
type Output = T;
fn unit(&self) -> Array1<T> {
self / (self * self).sum().sqrt()
}
}
Note that Unit
now returns an associated type. If you want it to always return f32
then you'll need to require that T
can be converted to f32
too.