I think you are using generics incorrectly, and this is the root of your problem.
Generics in Rust have inputs and outputs:
- Inputs are specified as parameters between
<> - Outputs (also called associated types) are indicated inside the type
The intuition is that for a given set of inputs, one type is selected for each output.
In your case, we must rework the features for this:
trait Add<Rhs: Nat>: Nat { type Result: Nat; }
A trait definition says:
Add requires Self be NatAdd implemented for the right argument, which should be Nat- This
Add implementation is of type Result , which must be Nat
Now we can implement this:
impl<T: Nat> Add<T> for Zero { type Result = T; } impl<A: Nat, B: Nat> Add<B> for Succ<A> where A: Add<Succ<B>> { type Result = < A as Add<Succ<B>> >::Result; }
Note that the functions are completely unnecessary, the result is "A + B":
<A as Add<B>>::Result
Now let's move on to multiplication:
trait Mul<Rhs: Nat>: Nat { type Result: Nat; } impl<T: Nat> Mul<T> for Zero { type Result = Zero; } // The first attempt does not work, but I'm keeping it here as // it is good for learning purpose. // // impl<A: Nat, B: Nat> Mul<B> for Succ<A> // where A: Mul<B> + Add< <A as Mul<B>>::Result > // { // type Result = <A as Add< <A as Mul<B>>::Result >>::Result; // } // // Think: // 1. Why exactly does it not work? // 2. What exactly is going on here? // 3. How would you multiply numbers in terms of addition? // 4. m * n = m + m + m ... (n times)? Or: n + n + .. (m times)? // // Answering these questions will help learning the intricacies of // Rust traits/type-system and how they work. impl<A: Nat, B: Nat> Mul<B> for Succ<A> where A: Mul<B>, B: Add<<A as Mul<B>>::Result>, { type Result = <B as Add<<A as Mul<B>>::Result>>::Result; }
And this now compiles:
fn main() { type One = Succ<Zero>; type Two = <One as Add<One>>::Result; type Four = <Two as Mul<Two>>::Result; }
Note that such Peano arithmetic has quite annoying limitations, especially in the depth of the recursion. Your addition is O (N), the multiplication is O (N ^ 2), ...
If you are interested in more efficient representations and calculations, I advise you to check the box type type, which is modern.