type-fn 0.2.0

Allows for simpler coding of type-level logic, e.g. for type-number systems.
Documentation
use std::marker::PhantomData;

use type_fn::*;

pub struct Zero;
pub struct Succ<T>(PhantomData<T>);
pub trait ToNum<NumType> {
    const RESULT: NumType;
}
impl ToNum<usize> for Zero {
    const RESULT: usize = 0;
}
impl<T> ToNum<usize> for Succ<T>
where
    T: ToNum<usize>,
{
    const RESULT: usize = T::RESULT + 1;
}
type_fn! {
    pub fn Add<Lhs, Rhs>;
    pub fn Sub<Lhs, Rhs>;
    pub fn Mul<Lhs, Rhs>;
    pub fn Pow<N, Exponent>;

    pub fn Root<V, N>;

    pub fn DistanceDirect<DistX, DistY>;
}
type_fn_impl! {
    fn Add< => Zero, Rhs> => Rhs;
    fn Add<N => Succ<N>, Rhs>
        where
            Add<N, Rhs>: + TypeFn,
        => Succ<call!(Add<N, Rhs>)>;

    fn Sub<Lhs, => Zero> => Lhs;
    fn Sub<Lhs => Succ<Lhs>, Rhs => Succ<Rhs>>
        where
            Sub<Lhs, Rhs> : + TypeFn,
        => call!(Sub<Lhs, Rhs>);

    fn Mul< => Zero, Rhs> => Zero;
    fn Mul<Lhs => Succ<Lhs>, Rhs>
        where
            Mul<Lhs, Rhs>: + TypeFn,
            Add<Rhs, call!(Mul<Lhs, Rhs>)>: + TypeFn,
        => call!(Add<Rhs, call!(Mul<Lhs, Rhs>)>);

    fn Pow<N, => Zero> => Succ<Zero>;
    fn Pow<N, Exp => Succ<Exp>>
        where
            Pow<N, Exp>: + TypeFn,
            Mul<N, call!(Pow<N, Exp>)>: + TypeFn,
        => call!(Mul<N, call!(Pow<N, Exp>)>);
}

fn main() {
    type One = Succ<Zero>;
    type Two = call!(Add<One, One>);
    type Five = call!(Add<One, call!(Add<Two, Two>)>);
    println!("2^5: {}", <call!(Pow<Two, Five>) as ToNum<usize>>::RESULT);
}