same-as 1.0.0

Type equality in stable Rust.
Documentation
  • Coverage
  • 100%
    2 out of 2 items documented1 out of 2 items with examples
  • Size
  • Source code size: 4.79 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 511.54 kB This is the summed size of all files generated by rustdoc for all configured targets
  • Links
  • wrsturgeon/same-as
    2 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • wrsturgeon

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); } // Please don't actually write this
struct MrCreosote;
impl Eat<u8> for MrCreosote { fn eat<U: SameAs<u8>>(_: U) {} }
MrCreosote::eat(0_u8); // wafer-thin type

This won't compile:

// ...
struct MrCreosote;
impl Eat<u8> for MrCreosote { fn eat<U: SameAs<u8>>(_: U) {} }
MrCreosote::eat(0_u16); // kaboom

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>> { // <-- Enforces that e.g. for `Maybe<A>`, `Self::Constructor` is effectively just the type constructor `Maybe`.
    type Constructor<B>: Monad<B>; // In this `impl`, `Self` is really `Self<A>`, but we want to make `Self<B>` below.
    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) } // deception!  vvvvvv
impl<A> Monad<A> for Maybe<A> { type Constructor<B> = Option<B>; }