5
我試圖在Rust中實現類型級乘法。生鏽的類型級乘法
加法已經在工作,但我得到了一個「臨時」類型變量的問題。
代碼:
use std::marker::PhantomData;
//Trait for the type level naturals
trait Nat {}
impl Nat for Zero {}
impl<T: Nat> Nat for Succ<T> {}
//Zero and successor types
struct Zero;
struct Succ<T: Nat>(PhantomData<T>);
//Type level addition
trait Add<B,C>
where Self: Nat,
B: Nat,
C: Nat
{}
impl<B: Nat> Add<B,B> for Zero {}
impl<A: Nat,B: Nat,C: Nat> Add<B,C> for Succ<A>
where A: Add<Succ<B>,C>
{}
fn add<A: Nat, B: Nat, C: Nat>(
a: PhantomData<A>,
b: PhantomData<B>)
-> PhantomData<C>
where A: Add<B,C> { PhantomData }
//Type level multiplication
trait Mult<B,C>
where Self: Nat,
B: Nat,
C: Nat,
{}
impl<B: Nat> Mult<B,Zero> for Zero {}
//ERROR HERE: "unconstrained type parameter 'C'"
//impl<A: Nat, B: Nat,C: Nat, D: Nat> Mult<B,D> for Succ<A>
// where A: Mult<B,C>,
// B: Add<C,D>
// {}
fn main() {
let x: PhantomData<Succ<Succ<Zero>>> = PhantomData;
let y: PhantomData<Succ<Zero>> = PhantomData;
//uncomment ': i32' in the next line to see infered type
let z /*: i32*/ = add(x,y);
}
張貼的代碼編譯就好及加建工程。 如果我取消了ERROR HERE節我收到以下錯誤信息:
error[E0207]: the type parameter `C` is not constrained by the impl trait, self type, or predicates
--> src/main.rs:40:21
|
40 | impl<A: Nat, B: Nat,C: Nat, D: Nat> Mult<B,D> for Succ<A>
| ^unconstrained type parameter
error: aborting due to previous error
error: Could not compile `4_18_generics`.
To learn more, run the command again with --verbose.
有沒有使用這些「臨時/中間」類型參數的方法嗎?
乘法可能以任何其他方式(我目前沒有想到)?
通常不可能嗎?
在將來的語言版本中可能嗎?
我試圖像Haskell那樣做(反正有點......)。我知道不要把這種東西放在船上。 :-)謝謝你的出色答案! – Lazarus535
@ Lazarus535:但是...但是...太空船是有趣的! :D –
它絕對是!我實際上正在重寫一個現在在Rust的小項目,但我總是被這些東西分散注意力。 :-D – Lazarus535