struct Foo;
Then we can make a trait, that defines an interface that we can give to data later: trait Bar {
const BAR_CONSTANT: i32;
fn some_function();
fn some_method(self);
}
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.Here's all this code on the Rust interactive playground if you'd like to poke at it: https://play.rust-lang.org/?gist=60bd64e1b2f52bb91ed0b0cb428...
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.
There is "parametric" vs "ad-hoc". https://stackoverflow.com/questions/6730126/parametric-polym... has a link to the text of TAPL explaining the difference here.
Rust traits and Haskell typeclasses would be ad-hoc.
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)