I wanted to write a simple implementation of Peano numbers in Rust and it seems that I managed to get the basics working:
use self::Peano::*;
use std::ops::Add;
#[derive(Debug, PartialEq)]
enum Peano {
Zero,
Succ(Box<Peano>)
}
impl Add for Peano {
type Output = Peano;
fn add(self, other: Peano) -> Peano {
match other {
Zero => self,
Succ(x) => Succ(Box::new(self + *x))
}
}
}
fn main() {
assert_eq!(Zero + Zero, Zero);
assert_eq!(Succ(Box::new(Zero)) + Zero, Succ(Box::new(Zero)));
assert_eq!(Zero + Succ(Box::new(Zero)), Succ(Box::new(Zero)));
assert_eq!(Succ(Box::new(Zero)) + Succ(Box::new(Zero)), Succ(Box::new(Succ(Box::new(Zero)))));
assert_eq!(Succ(Box::new(Zero)) + Zero + Succ(Box::new(Zero)), Succ(Box::new(Succ(Box::new(Zero)))));
}
However, when I decided to take look at how it was implemented by others, I saw that noone decided to do it with an enum
, but rather with struct
s and PhantomData
(example 1, example 2).
Is there something wrong with my implementation? Is this because Zero
and Succ
are enum
variants and not true types (so my implementation is not actual type arithmetic)? Or is it just preferable to do this the "mainstream" way due to difficulties that would occur if I expanded my implementation?
Edit: my struggles with implementing Peano numbers using struct
s can be seen here.