Diffstat (limited to 'src/hkt.rs')
-rw-r--r--src/hkt.rs143
1 files changed, 123 insertions, 20 deletions
diff --git a/src/hkt.rs b/src/hkt.rs
index 58539db..83a051e 100644
--- a/src/hkt.rs
+++ b/src/hkt.rs
@@ -100,6 +100,7 @@ pub use higher_ranked_type;
#[macro_export]
macro_rules! bijective_higher_ranked_trait {
{
+ $(#[$($meta:tt)*])*
$vis:vis type class $name:ident[
$($lifetimes:lifetime),*
][
@@ -112,53 +113,151 @@ macro_rules! bijective_higher_ranked_trait {
$($for_bound:tt)*
})?
} => {
+ $(#[$($meta)*])*
$vis mod $name {
#![allow(unused, non_snake_case)]
use super::*;
- pub trait LowerForLt<$lt, $($lifetimes,)* B, $($generic),*> $(: $($self_provides)*)?
- where $($($bound)*)? $($($for_bound)*)?
-
+ /// Trait for lowering a higher ranked type to a lower type.
+ ///
+ /// Do not use this trait directly instead use the [`MemberType`] trait and [`T`]
+ /// type alias.
+ ///
+ /// This acts to inject a lifetime into the higher ranked type to make it concrete.
+ pub trait LowerForLt<$lt, $($lifetimes: $lt,)* B: $lt, $($generic: $lt),*> $(: $($self_provides)*)?
+ where
+ $($($bound)*)?
+ $($($for_bound)*)?
{
- type T: ?Sized + RaiseForLt<$lt, $($lifetimes,)* B, $($generic,)* HigherRanked = Self> $(+ $($provides)+)? + $lt;
+ /// The lower type for this higher ranked type.
+ ///
+ /// The lower type must live for a minimum of the injected lifetime.
+ ///
+ /// Note this type must be raisable back to the same higher ranked type to make
+ /// this a bijective mapping.
+ type T: ?Sized + RaiseForLt<
+ $lt,
+ $($lifetimes,)*
+ &$lt ($(&$lifetimes (),)* $($generic),*),
+ $($generic,)*
+ HigherRanked = Self
+ > $(+ $($provides)+)? + $lt;
}
- pub trait RaiseForLt<$lt, $($lifetimes,)* B, $($generic),*>
- where $($($bound)*)? $($($for_bound)*)?
-
+ /// Trait for raising a lower type to it's higher ranked form.
+ ///
+ /// Do not use this trait directly instead use the [`LowerType`] trait and [`HigherRanked`]
+ /// type alias.
+ ///
+ /// this acts to remove a lifetime from the lower type.
+ pub trait RaiseForLt<$lt, $($lifetimes: $lt,)* B: $lt, $($generic: $lt),*>
+ where
+ $($($bound)*)?
+ $($($for_bound)*)?
{
- type HigherRanked: ?Sized + LowerForLt<$lt, $($lifetimes,)* B, $($generic,)* T = Self> + $($lifetimes +)*;
+ /// The higher ranked type for this lower type.
+ ///
+ /// Note this type must be lowerable back to the same lower type to make
+ /// this a bijective mapping.
+ type HigherRanked: ?Sized + LowerForLt<
+ $lt,
+ $($lifetimes,)*
+ &$lt ($(&$lifetimes (),)* $($generic),*),
+ $($generic,)*
+ T = Self
+ > $(+ $lifetimes)*;
}
- pub trait Trait<$($lifetimes,)* $($generic),*>:
- for<$lt> LowerForLt<$lt, $($lifetimes,)* &$lt ($(&$lifetimes (),)* $($generic),*), $($generic),*>
+ /// Trait for higher ranked types of this form.
+ ///
+ /// A higher ranked type can have a lifetime injected to form a lower type.
+ /// To perform this operation use the [`T`] type alias.
+ ///
+ /// This is basically a trait alias for the bound `for<'a> LowerForLt<'a, ...>`.
+ pub trait MemberType<$($lifetimes,)* $($generic),*>:
+ for<$lt> LowerForLt<
+ $lt,
+ $($lifetimes,)*
+ // Use a implied bound to make sure the lifetime from the for syntax is
+ // correctly bounded.
+ &$lt ($(&$lifetimes (),)* $($generic),*),
+ $($generic),*
+ >
where
$($($bound)*)?
{}
- impl<$($lifetimes,)* __: ?Sized, $($generic),*> Trait<$($lifetimes,)* $($generic),*> for __
+ // Impl the higher ranked trait for all higher ranked types with the ability to lower.
+ impl<
+ $($lifetimes,)*
+ __: ?Sized,
+ $($generic),*
+ > MemberType<$($lifetimes,)* $($generic),*> for __
where
- __: for<$lt> LowerForLt<$lt, $($lifetimes,)* &$lt ($(&$lifetimes (),)* $($generic),*), $($generic),*>,
+ __: for<$lt> LowerForLt<
+ $lt,
+ $($lifetimes,)*
+ &$lt ($(&$lifetimes (),)* $($generic),*),
+ $($generic),*
+ >,
$($($bound)*)?
{}
- pub type T<$lt, $($lifetimes,)* __, $($generic),*> = <__ as LowerForLt<$lt, $($lifetimes,)* &$lt ($(&$lifetimes (),)* $($generic),*), $($generic),*>>::T;
-
- pub trait Member<$lt, $($lifetimes,)* $($generic),*>: RaiseForLt<$lt, $($lifetimes,)* &$lt ($(&$lifetimes (),)* $($generic),*), $($generic),*> $(+ $($provides)+)?
+ /// Inject a lifetime into a higher ranked type to form its lower type.
+ pub type T<$lt, $($lifetimes,)* __, $($generic),*> =
+ <__ as LowerForLt<
+ $lt,
+ $($lifetimes,)*
+ &$lt ($(&$lifetimes (),)* $($generic),*),
+ $($generic),*
+ >>::T;
+
+ /// Trait for lower types with a higher ranked form.
+ ///
+ /// A lower type can have a lifetime removed to form a higher ranked type.
+ /// To perform this operation use the [`HigherRanked`] type alias.
+ ///
+ /// This is basically a trait alias for the bound `RaiseForLt<'a, ...>`.
+ pub trait LowerType<
+ $lt,
+ $($lifetimes: $lt,)*
+ $($generic: $lt),*
+ >: RaiseForLt<
+ $lt,
+ $($lifetimes,)*
+ &$lt ($(&$lifetimes (),)* $($generic),*),
+ $($generic),*
+ > $(+ $($provides)+)?
where
- ($(&$lifetimes (),)*): $lt,
$($($bound)*)?
{}
- impl<$lt, $($lifetimes,)* __: ?Sized, $($generic),*> Member<$lt, $($lifetimes,)* $($generic),*> for __
+ // Impl the lower type trait for all lower types with the ability to raise.
+ impl<
+ $lt,
+ $($lifetimes: $lt,)*
+ __: ?Sized,
+ $($generic: $lt),*
+ > LowerType<$lt, $($lifetimes,)* $($generic),*> for __
where
- __: RaiseForLt<$lt, $($lifetimes,)* &$lt ($(&$lifetimes (),)* $($generic),*), $($generic),*> $(+ $($provides)+)?,
- ($(&$lifetimes (),)*): $lt,
+ __: RaiseForLt<
+ $lt,
+ $($lifetimes,)*
+ &$lt ($(&$lifetimes (),)* $($generic),*),
+ $($generic),*
+ > $(+ $($provides)+)?,
$($($bound)*)?
{}
- pub type HigherRanked<$lt, $($lifetimes,)* __, $($generic),*> = <__ as RaiseForLt<$lt, $($lifetimes,)* &$lt ($(&$lifetimes (),)* $($generic),*), $($generic),*>>::HigherRanked;
+ /// Remove a lifetime into a lower type to form its higher ranked type.
+ pub type HigherRanked<$lt, $($lifetimes,)* __, $($generic),*> =
+ <__ as RaiseForLt<
+ $lt,
+ $($lifetimes,)*
+ &$lt ($(&$lifetimes (),)* $($generic),*),
+ $($generic),*
+ >>::HigherRanked;
}
};
}
@@ -171,6 +270,7 @@ pub use bijective_higher_ranked_trait;
#[macro_export]
macro_rules! bijective_higher_ranked_type {
{
+ $(#[$($meta:tt)*])*
$vis:vis type $name:ident[
$($ctx:lifetime),*
][
@@ -183,6 +283,7 @@ macro_rules! bijective_higher_ranked_type {
($higher_ranked_type:ty)
$(where {$($bound:tt)*})?
} => {
+ $(#[$($meta)*])*
$vis struct $name<
$($type_class_lifetime,)*
$($generic: ?Sized,)*
@@ -305,6 +406,7 @@ macro_rules! bijective_higher_ranked_type {
};
};
{
+ $(#[$($meta:tt)*])*
$vis:vis type $name:ident[
$($ctx:lifetime),*
][
@@ -317,6 +419,7 @@ macro_rules! bijective_higher_ranked_type {
$(where {$($bound:tt)*})?
} => {
$crate::hkt::bijective_higher_ranked_type! {
+ $(#[$($meta)*])*
$vis type $name[
$($ctx),*
][