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
我们都知道 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。