• Stars
    star
    357
  • Rank 119,149 (Top 3 %)
  • Language
    Rust
  • License
    MIT License
  • Created over 4 years ago
  • Updated almost 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

We all know Rust's trait system is Turing complete, so tell me, why aren't we exploiting this???

trait_eval

Crates.io Build Status lines of code Minimum rustc 1.43

We all know Rust's trait system is Turing complete, so tell me, why aren't we exploiting this??? Who needs const-fn when we've got a crate like this?!

Honestly, I was too preoccupied with the fact that I could to stop to think whether I actually should.

Believe it or not, I even wrote docs for this.

Example

Here's an eminently readable example where we play FizzBuzz at compile-time!

trait FizzBuzzType {
    fn show() -> String; // Don't worry about this -- it's just so we can print the result
}

struct Fizz;

impl FizzBuzzType for Fizz {
    fn show() -> String {
        "Fizz".to_string()
    }
}

struct Buzz;

impl FizzBuzzType for Buzz {
    fn show() -> String {
        "Buzz".to_string()
    }
}

struct FizzBuzz;

impl FizzBuzzType for FizzBuzz {
    fn show() -> String {
        "FizzBuzz".to_string()
    }
}

impl<T: Nat> FizzBuzzType for T
where
    T: Eval,
    <T as Eval>::Output: Display,
{
    fn show() -> String {
        format!("{}", T::eval())
    }
}

trait FizzBuzzEval: Nat {
    type Result: FizzBuzzType;
}

impl<T: Nat,
    Mod3: Nat,
    Mod5: Nat,
    ShouldFizz: Bool,
    ShouldBuzz: Bool,
    ShouldFizzBuzz: Bool,
    DidBuzz: FizzBuzzType,
    DidFizz: FizzBuzzType,
    DidFizzBuzz: FizzBuzzType> FizzBuzzEval for T
where
    T: Mod<Three, Result = Mod3> + Mod<Five, Result = Mod5>,
    Mod3: Equals<Zero, Result = ShouldFizz>,
    Mod5: Equals<Zero, Result = ShouldBuzz>,
    ShouldFizz: AndAlso<ShouldBuzz, Result = ShouldFizzBuzz>,
    (Fizz, T): If<ShouldFizz, Result = DidFizz>,
    (Buzz, DidFizz): If<ShouldBuzz, Result = DidBuzz>,
    (FizzBuzz, DidBuzz): If<ShouldFizzBuzz, Result = DidFizzBuzz>,
{
    type Result = DidFizzBuzz;
}

assert_eq!(<One as FizzBuzzEval>::Result::show(), "1");
assert_eq!(<Two as FizzBuzzEval>::Result::show(), "2");
assert_eq!(<Three as FizzBuzzEval>::Result::show(), "Fizz");
assert_eq!(<Four as FizzBuzzEval>::Result::show(), "4");
assert_eq!(<Five as FizzBuzzEval>::Result::show(), "Buzz");
assert_eq!(<Six as FizzBuzzEval>::Result::show(), "Fizz");
assert_eq!(<Seven as FizzBuzzEval>::Result::show(), "7");
assert_eq!(<Eight as FizzBuzzEval>::Result::show(), "8");
assert_eq!(<Nine as FizzBuzzEval>::Result::show(), "Fizz");
assert_eq!(<Ten as FizzBuzzEval>::Result::show(), "Buzz");

type Fifteen = <Three as Times<Five>>::Result;
assert_eq!(<Fifteen as FizzBuzzEval>::Result::show(), "FizzBuzz"); // !!!

Contributing

Please, for the love of God, don't use this crate. If you must contribute, open a PR.

Projects using this crate

Some people never listen, huh?

  • fortraith - Forth implemented in the Rust trait system