tytro 0.1.0

类型上的尾递归优化
Documentation
use tytro::tytro;

#[tytro]
enum List<T> {
    Nil,
    Cons(T, Self),
}

impl List<u32> {
    fn range(x: u32) -> Self {
        match x {
            0 => ListF::Nil,
            _ => ListF::Cons(x - 1, Self::range(x - 1)),
        }
        .build()
    }
}

impl<T> List<T> {
    fn concat(self, rhs: Self) -> Self {
        self.foldr(rhs, &|x, rhs| ListF::Cons(x, rhs).build())
    }

    fn foldr<R>(self, init: R, f: &impl Fn(T, R) -> R) -> R {
        match self.get() {
            ListF::Nil => init,
            ListF::Cons(x, xs) => f(x, xs.foldr(init, f)),
        }
    }
}

impl ListRef<'_, u32> {
    fn sum(self) -> u32 {
        self.foldl(0, |sum, &x| sum + x)
    }
}

impl<T> ListRef<'_, T> {
    fn foldl<R>(self, init: R, f: impl Fn(R, &T) -> R) -> R {
        match self.get_ref() {
            ListFRef::Nil => init,
            ListFRef::Cons(x, xs) => xs.foldl(f(init, x), f),
        }
    }
}

#[test]
fn test_nat() {
    let l1 = List::range(10);
    let l2 = ListF::Cons(114, ListF::Cons(514, ListF::Nil.build()).build()).build();

    assert_eq!(l1.as_ref().sum(), 45);
    assert_eq!(l2.as_ref().sum(), 628);
    assert_eq!(l1.concat(l2).as_ref().sum(), 673);
}