#traits #compile-time #evaluator #const #satire

trait_eval

我们都知道 Rust 的特质系统是图灵完备的,那么告诉我,我们为什么不去利用这个呢???

4 个版本

0.1.3 2020 年 5 月 26 日
0.1.2 2020 年 5 月 24 日
0.1.1 2020 年 5 月 24 日
0.1.0 2020 年 5 月 24 日

#30#evaluator


用于 fortraith

自定义许可证

20KB
234 行代码(不包括注释)

trait_eval

Crates.io Build Status lines of code Minimum rustc 1.43

我们都知道 Rust 的特质系统是图灵完备的,那么告诉我,我们为什么不去利用这个呢???谁还需要 const-fn 当我们有这样的 crate 的时候?!

说实话,我太专注于我能够做到的事情,以至于没有停下来思考我实际上是否应该这么做。

信不信由你,我甚至为此写了文档[链接].

示例

这是一个非常易于阅读的示例,我们在编译时玩 FizzBuzz!

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"); // !!!

贡献

请,为了上帝的爱,不要使用这个 crate。如果你必须贡献,请发起一个 PR。

无运行时依赖