Пеано цифры в Русте

Я хотел написать простую реализацию чисел Пеано в Rust, и, похоже, мне удалось заставить работать основы:

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)))));
}

Однако, когда я решил посмотреть, как это было реализовано другими, я увидел, что никто не решил сделать это с enum, а скорее с structс и PhantomData ( пример 1, пример 2).

Что-то не так с моей реализацией? Это потому что Zero а также Succ являются enum варианты и не истинные типы (так что моя реализация не фактическая арифметика типов)? Или это просто предпочтительнее сделать "основным" способом из-за трудностей, которые возникнут, если я расширю свою реализацию?

Изменить: моя борьба с реализацией чисел Пеано с использованием structс можно увидеть здесь.

1 ответ

Решение

Ваши числа Пеано находятся на уровне значений, которые используются для вычислений во время работы программы. Это хорошо для игры, но не очень полезно, потому что двоичные числа, такие как i32 гораздо эффективнее.

Другие реализации представляют числа Пеано на уровне типа, где в настоящее время вы не можете использовать обычные числа. Это позволяет выражать типы, которые зависят от числа, например, массивы фиксированного размера. Затем вычисления выполняются, когда компилятор выводит типы.

Другие вопросы по тегам