1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#![no_std]

use core::ops::*;

#[derive(Copy)] pub enum Zero {}
#[derive(Clone, Copy)] pub struct Succ<N: Natural>(N);

impl Clone for Zero {
    fn clone(&self) -> Self { match *self {} }
}

pub trait Natural {
    fn to_usize() -> usize;
}

impl Natural for Zero {
    fn to_usize() -> usize { 0 }
}

impl<N: Natural> Natural for Succ<N> {
    fn to_usize() -> usize { 1+N::to_usize() }
}

impl<N: Natural> Add<N> for Zero {
    type Output = N;
    fn add(self: Zero, n: N) -> N { n }
}

impl<M: Natural, N: Natural> Add<N> for Succ<M> where M: Add<N>, <M as Add<N>>::Output: Natural {
    type Output = Succ<<M as Add<N>>::Output>;
    fn add(self: Succ<M>, n: N) -> Self::Output { let Succ(m) = self; Succ(m+n) }
}