Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upAdd bounds aliases #804
Comments
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
Yes, I've often wanted this. I'm not sure if there are any tricky issues with having trait aliases. I expect we would 'desugar' them early in the process, once we've done name resolution and privacy checking, so they should have no effect on trait matching, which is probably the most complex part of the compiler now. |
This comment has been minimized.
This comment has been minimized.
|
Yeah, I've experienced the pain of not having this when binding a c library that is callback-heavy. We definitely need this. I think it requires a formal RFC though, no? Either way you have my support. |
This comment has been minimized.
This comment has been minimized.
|
Note that we can do something similar using blanket impls: trait Callback<T>: FnMut(T) -> Response + Send + 'static {}
impl<S, T> Callback<T> for S where S: FnMut(T) -> Response + Send + 'static {}I think this is what @nick29581 means by desugaring. As an aside, associated bounds could be useful in combination with HKT. For example, if we grow a // Imaginary syntax!
trait Monad for type<type> {
trait Value;
fn pure<A>(value: A) -> Self<A> where A: Value;
fn flat_map<F, A, B>(self, callback: F) where F: FnOnce(A) -> Self<B>, A: Value, B: Value;
}
impl Monad for BTreeSet<type> {
trait Value = Ord;
// ...
}
impl Monad for Future<type> {
trait Value = Send;
// ...
}
impl Monad for HashSet<type> {
trait Value = Hash;
// ...
}I don't know the full implications of such a change, though. I'll leave it to someone more experienced with the compiler to chime in. Overall, I'm on the fence about this proposal. If we ignore associated bounds, this whole thing is just sugar for a new trait + blanket impl. A bit annoying to type, yes, but nothing a better macro system can't fix. Haskell went without bounds aliases for years, and when it was finally introduced, it was as a cute side-effect of a larger generalization (unifying types and bounds). Plus, Haskell has stricter rules for blanket impls, so they couldn't even use that trait/impl trick without hacks. So while there is support for this feature, and it seems easy to implement, I'm not sure if it's worth it right now. Do we have any real-world examples that would benefit from this extension? |
This comment has been minimized.
This comment has been minimized.
They can, it just requires |
This comment has been minimized.
This comment has been minimized.
crumblingstatue
commented
Jun 23, 2015
|
I have bumped into this. type Pred = Fn(&str) -> bool + 'static;
trait PredTrait: Fn(&str) -> bool + 'static {}
impl <T: Fn(&str) -> bool + 'static> PredTrait for T {}
struct Foo {
predicate: Box<Pred>,
text: String,
}
impl Foo {
fn check(&self) {
match (*self.predicate)(&self.text) {
true => println!("Predicate is satisfied"),
false => println!("Predicate is not satisfied."),
}
}
}
struct FooBuilder {
predicate: Box<Pred>,
text: String,
}
impl FooBuilder {
fn new() -> Self {
FooBuilder {
predicate: Box::new(|_| true),
text: String::new(),
}
}
fn predicate<T: PredTrait>(mut self, predicate: T) -> Self {
self.predicate = Box::new(predicate);
self
}
fn text(mut self, text: String) -> Self {
self.text = text;
self
}
fn build(self) -> Foo {
Foo {
predicate: self.predicate,
text: self.text,
}
}
}
fn main() {
let foo = FooBuilder::new().text("hello".to_owned())
.predicate(|s| s == "world").build();
foo.check();
}
The new trait + blanket impl solution is not only ugly, but results in weird type mismatch errors, and can't be used as |
This comment has been minimized.
This comment has been minimized.
narfanar
commented
Jun 23, 2015
|
I'm in favor of an Or just make |
This comment has been minimized.
This comment has been minimized.
|
I guess we can relate to #1733 here? |
This comment has been minimized.
This comment has been minimized.
|
Closing in favor of #1733 |
lfairy commentedFeb 3, 2015
Writing out trait bounds over and over again can be tiring, especially with unboxed closures.
It would be nice if we could abbreviate these, just like we do with types:
Note that the alias is used as a bound, not a type. This is what sets it apart from normal type aliases, which Rust supports already.
GHC Haskell supports something similar with constraint kinds. Notably, they allow a restricted form of associated bounds.