Add another example, add call_as!

This commit is contained in:
Daniella / Tove 2023-11-15 15:41:33 +01:00
parent 42f2118834
commit c7b95ea0eb
Signed by: TudbuT
GPG key ID: B3CF345217F202D3
4 changed files with 77 additions and 14 deletions

View file

@ -1,6 +1,6 @@
[package]
name = "type-fn"
version = "0.1.1"
version = "0.1.2"
edition = "2021"
description = "Allows for simpler coding of type-level logic, e.g. for type-number systems."
license = "MIT"

View file

@ -28,19 +28,13 @@ fn main() {
struct World;
type MyListA = EmptyList;
type MyListB = <AddElement<MyListA, World> as TypeFn>::Ret;
type MyListC = <AddElement<MyListB, Hello> as TypeFn>::Ret;
type MyListB = call!(AddElement<MyListA, World>);
type MyListC = call!(AddElement<MyListB, Hello>);
type RemovalA = <RemoveLastElement<MyListC> as TypeFn>::Ret;
println!(
"{}",
any::type_name::<<GetRemoved<RemovalA> as TypeFn>::Ret>()
);
type RemovalA = call!(RemoveLastElement<MyListC>);
println!("{}", any::type_name::<call!(GetRemoved<RemovalA>)>());
type MyListD = <GetChangedList<RemovalA> as TypeFn>::Ret;
type RemovalB = <RemoveLastElement<MyListD> as TypeFn>::Ret;
println!(
"{}",
any::type_name::<<GetRemoved<RemovalB> as TypeFn>::Ret>()
);
type MyListD = call!(GetChangedList<RemovalA>);
type RemovalB = call!(RemoveLastElement<MyListD>);
println!("{}", any::type_name::<call!(GetRemoved<RemovalB>)>());
}

62
examples/math.rs Normal file
View file

@ -0,0 +1,62 @@
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<TypeFn> Add< => Zero, Rhs> => Rhs;
fn<TypeFn> Add<N => Succ<N>, Rhs>
where
Add<N, Rhs>: + TypeFn,
=> Succ<call!(Add<N, Rhs>)>;
fn<TypeFn> Sub<Lhs, => Zero> => Lhs;
fn<TypeFn> Sub<Lhs => Succ<Lhs>, Rhs => Succ<Rhs>>
where
Sub<Lhs, Rhs> : + TypeFn,
=> call!(Sub<Lhs, Rhs>);
fn<TypeFn> Mul< => Zero, Rhs> => Zero;
fn<TypeFn> 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<TypeFn> Pow<N, => Zero> => Succ<Zero>;
fn<TypeFn> 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);
}

View file

@ -13,6 +13,13 @@ macro_rules! call {
};
}
#[macro_export]
macro_rules! call_as {
($fty:ty => $($fn:tt)+) => {
<$($fn)+ as $fty>::Ret
};
}
/// Verifies equality between two types at compile-time.
#[macro_export]
macro_rules! assert_types_eq {