Hi! I has been writing projects and I noticed something, some times we have some... elements, lets say a number will be anything where we can +, -, *, /, anything that supports that operations, the only way I know to group them and request them as a condition for an algorithms is with something like:
But this have an issue, for each type we want to use we need to implement the trait, not only that, we can have for example f64, but is a foreign type, so we can't implement it and we are forced to use wrappers....
In some project, specify with super traits to declare the functionality of elements is nice, but in others we just want to consider something as a "type" something that has some properties, is like think them implicitly.
So, going back, how can we make "something" that changes this:
That is not the case when the implementation resides in the same crate as the trait you are implementing. Orphan rules prevent you from implementing foreign traits on foreign types, not your own traits on foreign types.
You can do this using a blanket implementation for every T that implements Sub, Div, Add and Mul. There actually already exist such a trait, num::traits::NumOps with such a blanket implementation.
thx correcting me about the Orphan rule and the comment
Still is just an example, any idea how to define an element in the way I put above?
This can happens with a lot of elements, and would be nice have a way to just say "I'll cal this group of traits with this name"
error[E0277]: cannot add `T` to `NoisyFloat<f64, FiniteChecker>`
--> src/main.rs:6:19
|
6 | let s = x + y;
| ^ no implementation for `NoisyFloat<f64, FiniteChecker> + T`
|
= help: the trait `Add<T>` is not implemented for `NoisyFloat<f64, FiniteChecker>`
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
5 | fn foo<T: num::traits::real::Real>(x: noisy_float::prelude::R64, y: T) where NoisyFloat<f64, FiniteChecker>: Add<T> {
| ++++++++++++++++++++++++++++++++++++++++++++
For more information about this error, try `rustc --explain E0277`.
error: could not compile `a` (bin "a") due to 1 previous error
R64 is a NoisyFloat<f64, FiniteChecker> and the Add implementation specifies that you can only add F to NoisyFloat<F, C>, so you can only add an f64 to a NoisyFloat<f64, FiniteChecker>. However, what you have in the function foo is a type T that implements Float or Real, which may be f64 but is not necessarily guaranteed to be f64. You need to either just use f64 or pass the parameter to the NoisyFloat.
Edit: To clarify, here is what just using f64 would look like:
fn foo(x: noisy_float::prelude::R64, y: f64) {
let s = x + y;
}
And this is what passing T to the NoisyFloat would look like:
fn foo<T: num::traits::float::Float>(x: noisy_float::NoisyFloat<T, FiniteChecker>, y: T) {
let s = x + y;
}