Then we can actually implement that trait for our data:
impl Bar for Foo {
const BAR_CONSTANT: i32 = 42;
fn some_function() {
println!("foo's associated function, and the const is {}", Self::BAR_CONSTANT);
}
fn some_method(self) {
println!("foo's method, and the const is still {}", Self::BAR_CONSTANT);
}
}
Then we can use it like so:
Foo::some_function(); // foo's associated function, and the const is 42
let foo = Foo;
foo.some_method(); // foo's method, and the const is still 42
And now we can take it further. Imagine that you have another piece of data, `struct Qux`. Then you can do the same and `impl Bar for Qux`. And now you can write a generic function like so:
fn bar_taker<T: Bar>(something_that_impls_bar: T) {
T::some_function();
something_that_impls_bar.some_method();
// And of course we can refer to T::BAR_CONSTANT in here as well.
}
And call it like so:
bar_taker(foo);
bar_taker(qux);
AFAIK, the big deal with associated consts is specifically that it allows generic code like that to refer to different values on a per-type basis.
Thanks for the nice example. I've heard of traits but hadn't read enough to know what they are. Looks like a form of multiple inheritance. The example you gave shows polymorphism via traits. That was helpful to me.
It may be easier to see their significance when they're associated with a trait, rather than a struct.
For a simple example, imagine I've got a trait Number, and every implementation of Number is supposed to have a zero constant. Then I could let that constant be Number::ZERO, and refer to it as such in generic code, with each implementation of Number having a different value for Number::ZERO.
That's interesting, I always assumed parametric polymorphism was a requirement of ad hoc polymorphism. I suppose I'm using a more narrow definition. On the opposite end,
Elm for instance, has parametric polymorphism:
type Parametric a = Parametric a
f : (a -> b) -> Parametric a -> Parametric b
f fn (Parametric a) = Parametric <| fn a
but no support for ad-hoc, like you said, in Haskell:
data Parametric a = Parametric a
f :: Ord a => Parametric a -> Parametric a -> Parametric a
f (Parametric a) (Parametric b) = Parametric (min a b)