[−][src]Crate trait_eval
Compile-Time Evaluation
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?!
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"); // !!!
Structs
False | False ( |
Succ | Peano-style increment operator |
True | True ( |
Zero | Constant zero ( |
Traits
AndAlso | Logical And |
Bool | The bool type ( |
Equals | Equality testing |
Eval |
|
Fact | Factorial! |
Fib | Built-in Fibonacci sequence |
If | Conditional execution! |
LessThan | Integer comparison |
Minus | Saturating Subtraction |
Mod | Remainders |
Nat | The type of natural numbers ( |
Not | Logical Not |
OrElse | Logical Or |
Plus | Addition |
Pred | Saturating Decrement |
Times | Multiplication |
Type Definitions
Eight | Constant eight ( |
Five | Constant five ( |
Four | Constant four ( |
Nine | Constant nine ( |
One | Constant one ( |
Seven | Constant seven ( |
Six | Constant six ( |
Ten | Constant ten ( |
Three | Constant three ( |
Two | Constant two ( |