diff --git a/Cargo.toml b/Cargo.toml
index ec9f865..ba65888 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "type-fn"
-version = "0.1.0"
+version = "0.1.1"
edition = "2021"
description = "Allows for simpler coding of type-level logic, e.g. for type-number systems."
license = "MIT"
diff --git a/examples/bools.rs b/examples/bools.rs
new file mode 100644
index 0000000..82315c2
--- /dev/null
+++ b/examples/bools.rs
@@ -0,0 +1,40 @@
+use type_fn::*;
+
+#[derive(Debug)]
+pub struct True;
+#[derive(Debug)]
+pub struct False;
+
+type_fn! {
+ pub fn Or;
+ pub fn And;
+ pub fn Xor;
+ pub fn Not;
+}
+
+type_fn_impl! {
+ fn Or< => True, B> => True;
+ fn Or< => False, B> => B;
+
+ fn And< => True, B> => B;
+ fn And< => False, B> => False;
+
+ fn Not< => True> => False;
+ fn Not< => False> => True;
+
+ fn Xor< => True, B>
+ where Not: + TypeFn,
+ => as TypeFn>::Ret;
+ fn Xor< => False, B> => B;
+}
+
+fn main() {
+ println!(
+ "True AND False: {}",
+ core::any::type_name::< as TypeFn>::Ret>()
+ );
+ println!(
+ "True OR False: {}",
+ core::any::type_name::< as TypeFn>::Ret>()
+ );
+}
diff --git a/examples/list.rs b/examples/list.rs
new file mode 100644
index 0000000..89b34b5
--- /dev/null
+++ b/examples/list.rs
@@ -0,0 +1,46 @@
+use std::{any, marker::PhantomData};
+
+use type_fn::*;
+
+pub struct EmptyList;
+pub struct ListExt(PhantomData, PhantomData);
+
+pub struct RemovalResult(PhantomData, PhantomData);
+
+type_fn! {
+ pub fn AddElement;
+ pub fn RemoveLastElement;
+
+ pub fn GetRemoved;
+ pub fn GetChangedList;
+}
+
+type_fn_impl! {
+ fn AddElement => ListExt;
+ fn RemoveLastElement ListExt | Element> => RemovalResult;
+
+ fn GetRemoved RemovalResult | List> => Element;
+ fn GetChangedList RemovalResult | Element> => List;
+}
+
+fn main() {
+ struct Hello;
+ struct World;
+
+ type MyListA = EmptyList;
+ type MyListB = as TypeFn>::Ret;
+ type MyListC = as TypeFn>::Ret;
+
+ type RemovalA = as TypeFn>::Ret;
+ println!(
+ "{}",
+ any::type_name::< as TypeFn>::Ret>()
+ );
+
+ type MyListD = as TypeFn>::Ret;
+ type RemovalB = as TypeFn>::Ret;
+ println!(
+ "{}",
+ any::type_name::< as TypeFn>::Ret>()
+ );
+}
diff --git a/src/lib.rs b/src/lib.rs
index 6ccda22..51c9b47 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -5,6 +5,14 @@ pub trait TypeFn {
type Ret;
}
+/// Calls a type-fn
+#[macro_export]
+macro_rules! call {
+ ($($fn:tt)+) => {
+ <$($fn)+ as TypeFn>::Ret
+ };
+}
+
/// Verifies equality between two types at compile-time.
#[macro_export]
macro_rules! assert_types_eq {
@@ -35,11 +43,11 @@ macro_rules! assert_types_eq {
/// You can define an arbitrary amount of functions in one macro invocation.
#[macro_export]
macro_rules! type_fn_impl {
- (@a_or_else_b => ) => {compiler_error!()};
- (@a_or_else_b => $($b:ident)+) => {$($b)*};
- (@a_or_else_b $($a:ty)+ => $($b:ident)*) => { $($a)+ };
- ($(fn < $sup:ty > $name:ident <$($($arg:ident)? $(=> $($argv:ty)+)?),* $(| $($targ:ident),+)?>
- $(where $($tv:ty : $( + $( ?$tcqm:ident )? $( $tc:ident )? )+ ,)+)? => $ret:ty;)+)
+ {@a_or_else_b => } => {compiler_error!()};
+ {@a_or_else_b => $($b:ident)+} => {$($b)*};
+ {@a_or_else_b $($a:ty)+ => $($b:ident)*} => { $($a)+ };
+ {$(fn < $sup:ty > $name:ident <$($($arg:ident)? $(=> $($argv:ty)+)?),* $(| $($targ:ident),+)?>
+ $(where $($tv:ty : $( + $( ?$tcqm:ident )? $( $tc:ident )? )+ ,)+)? => $ret:ty;)+}
=> {
$(
impl<$($($arg, )?)* $($($targ, )*)?>
@@ -107,7 +115,7 @@ mod tests {
type TwoMinusOne = >, Succ> as TypeFn>::Ret;
assert_types_eq!(TwoMinusOne, Succ);
- assert_types_eq!(> as TypeFn>::Ret, Zero);
+ assert_types_eq!(call!(Sub>), Zero);
assert_types_eq!(
Succ>>>,
>, Succ>> as TypeFn>::Ret