Reputation: 285
Is there any way to implement operator overloading for apply::Apply
?
In Rust, many of the operators can be overloaded via traits. That is, some operators can be used to accomplish different tasks based on their input arguments. This is possible because operators are syntactic sugar for method calls. For example, the + operator in a + b calls the add method (as in a.add(b)). This add method is part of the Add trait. Hence, the + operator can be used by any implementor of the Add trait.
/// Represents a type which can have functions applied to it (implemented
/// by default for all types).
pub trait Apply<Res> {
/// Apply a function which takes the parameter by value.
fn apply<F: FnOnce(Self) -> Res>(self, f: F) -> Res
where Self: Sized {
f(self)
}
}
impl<T: ?Sized, Res> Apply<Res> for T {
// use default definitions...
}
For instance,
let string = 1 >> (|x| x * 2) >> (|x: i32| x.to_string());
for
let string = 1.apply(|x| x * 2).apply(|x: i32| x.to_string());
Upvotes: 1
Views: 1562
Reputation: 393
Not really. Operators don't go on traits, they go on types. It does not make sense to ask "what is the implementation of >>
for Apply
" but it does make sense to ask "what is the implementation of >>
for u8
." So what you could try to do is to define Apply
as you've defined it, and now:
impl<T, Res, F> std::ops::Shr<F> for T
where
T: Apply<Res>,
F: FnOnce(T) -> Res
{
type Output = Res;
fn shr(self, rhs: F) -> Res {
rhs(self)
}
}
This almost works, except that the compiler reports an error, citing
only traits defined in the current crate can be implemented for a type parameter
The reason for this error is that you have no guarantee that another crate has not implemented the same trait for the same type. If another crate defined a
impl<F: FnOnce(MyType) -> String> std::ops::Shr<F> for MyType { ... }
its not clear what should happen, since now the >>
operator has been defined twice for the same type. You could write such an impl
if you replaced MyType
with some specific type that is local to your crate, but of course now the >>
thing won't work for all other types.
Upvotes: 2