Type equality in stable Rust.
Use
A toy example that demonstrates the basics:
use same_as::SameAs;
trait Eat<T> { fn eat<U: SameAs<T>>(_: U); } struct MrCreosote;
impl Eat<u8> for MrCreosote { fn eat<U: SameAs<u8>>(_: U) {} }
MrCreosote::eat(0_u8);
This won't compile:
struct MrCreosote;
impl Eat<u8> for MrCreosote { fn eat<U: SameAs<u8>>(_: U) {} }
MrCreosote::eat(0_u16);
But why is type equality necessary?
Sometimes you need it where Rust can't leverage it now, e.g. defining a Haskell-style monad in Rust:
pub trait Monad<A>: SameAs<Self::Constructor<A>> { type Constructor<B>: Monad<B>; fn bind<B, F: Fn(A) -> B>(self, f: F) -> Self::Constructor<B>;
}
So this would work:
pub enum Maybe<A> { Nothing, Just(A) }
impl<A> Monad<A> for Maybe<A> { type Constructor<B> = Maybe<B>; }
but we can prove that this won't, and so we can safely simulate type constructors in Rust:
pub enum Maybe<A> { Nothing, Just(A) } impl<A> Monad<A> for Maybe<A> { type Constructor<B> = Option<B>; }