I'm writing a generic function:
pub fn sort_by_axis<T>(data: &mut Vec<T>, ind: usize) {
}
that sorts the given data by ind-th coordinate. How to constraint the type T
to define that T[i]
returns a Float
type?
I'm writing a generic function:
pub fn sort_by_axis<T>(data: &mut Vec<T>, ind: usize) {
}
that sorts the given data by ind-th coordinate. How to constraint the type T
to define that T[i]
returns a Float
type?
where <T as Index>::Ouput: Float
Well, the compiler says:
error[E0576]: cannot find associated type `Ouput` in trait `Index`
--> src/main.rs:5:21
|
5 | where <T as Index>::Ouput: Float {
| ^^^^^ help: an associated type with a similar name exists: `Output`
--> /rustc/9eb3afe9ebe9c7d2b84b71002d44f4a0edac95e0/library/core/src/ops/index.rs:62:5
|
= note: similarly named associated type `Output` defined here
Here is the playground:
This looks like a spelling mistake to me, Ouput
is not an associated type of Index
, but Output
is
There is also another trait bound (T: Index<usize>
) and a generic parameter for Index
missing. Here a version of your code that compiles:
use num_traits::Float;
use std::ops::Index;
pub fn sort_by_axis<T>(data: &mut Vec<T>, ind: usize)
where
<T as Index<usize>>::Output: Float,
T: Index<usize>,
{
}
fn main() {
let mut data = vec![vec![0.0, 0.5], vec![0.7, 0.5], vec![0.8, 1.1]];
sort_by_axis(&mut data, 1);
}
Thanks! Now it works. But to finish that function I have to write the code that actually sorts. I've tried:
use std::ops::Index;
use num_traits::Float;
pub fn sort_by_axis<T>(data: &mut Vec<T>, idx: usize)
where <T as Index<usize>>::Output: Float, T: std::ops::Index<usize> {
data.sort_by(|a,b| b[idx].partial_cmp(&a[idx]));
}
fn main() {
let data = vec![vec![0.0, 0.5], vec![0.7, 0.5], vec![0.8, 1.1]];
sort_by_axis(&mut data,1);
}
but I got:
error[E0308]: mismatched types
--> src/main.rs:6:23
|
6 | data.sort_by(|a,b|b[idx].partial_cmp(&a[idx]));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Ordering`, found enum `Option`
|
= note: expected enum `std::cmp::Ordering`
found enum `Option<std::cmp::Ordering>`
Welcome to the strange world of float comparisons. You need to unwrap the result of partial_cmp
, because comparing floats is not that simple, i.e. NaN != NaN
.
data.sort_by(|a,b| b[idx].partial_cmp(&a[idx]).unwrap());
See e.g. this topic:
@H2CO3 recently shared a helpful link with more information about float comparisons, but unfortunately I don't recall which topic it was, nor do I remember the webpage.
Yes, thanks for re-sharing!