use core::marker::PhantomData;
pub trait HKT {
type Of<T>;
}
pub struct OptionF;
impl HKT for OptionF {
type Of<T> = Option<T>;
}
pub struct ResultF<E> {
_marker: PhantomData<E>,
}
impl<E> HKT for ResultF<E> {
type Of<T> = Result<T, E>;
}
#[cfg(any(feature = "std", feature = "alloc"))]
pub struct VecF;
#[cfg(any(feature = "std", feature = "alloc"))]
impl HKT for VecF {
#[cfg(feature = "std")]
type Of<T> = Vec<T>;
#[cfg(all(not(feature = "std"), feature = "alloc"))]
type Of<T> = alloc::vec::Vec<T>;
}
pub trait HKT2 {
type P<A, B>;
}
pub struct ResultBF;
impl HKT2 for ResultBF {
type P<A, B> = Result<B, A>;
}
pub struct TupleF;
impl HKT2 for TupleF {
type P<A, B> = (A, B);
}
pub struct IdentityF;
impl HKT for IdentityF {
type Of<T> = T;
}
#[cfg(any(feature = "std", feature = "alloc"))]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct NonEmptyVec<T> {
pub head: T,
pub tail: Vec<T>,
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<T> NonEmptyVec<T> {
pub fn new(head: T, tail: Vec<T>) -> Self {
Self { head, tail }
}
pub fn singleton(value: T) -> Self {
Self {
head: value,
tail: Vec::new(),
}
}
pub fn len(&self) -> usize {
1 + self.tail.len()
}
pub fn is_empty(&self) -> bool {
false }
pub fn iter(&self) -> impl Iterator<Item = &T> {
core::iter::once(&self.head).chain(self.tail.iter())
}
pub fn tails(&self) -> NonEmptyVec<NonEmptyVec<T>>
where
T: Clone,
{
let mut result_tail = Vec::new();
for i in 1..self.len() {
result_tail.push(NonEmptyVec::new(
self.tail[i - 1].clone(),
self.tail[i..].to_vec(),
));
}
NonEmptyVec::new(self.clone(), result_tail)
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
pub struct NonEmptyVecF;
#[cfg(any(feature = "std", feature = "alloc"))]
impl HKT for NonEmptyVecF {
type Of<T> = NonEmptyVec<T>;
}
pub struct EnvF<E>(PhantomData<E>);
impl<E> HKT for EnvF<E> {
type Of<T> = (E, T);
}
#[cfg(any(feature = "std", feature = "alloc"))]
pub struct StoreF<S>(PhantomData<S>);
#[cfg(any(feature = "std", feature = "alloc"))]
impl<S: 'static> HKT for StoreF<S> {
type Of<T> = (Box<dyn Fn(S) -> T>, S);
}
#[cfg(any(feature = "std", feature = "alloc"))]
pub struct TracedF<M>(PhantomData<M>);
#[cfg(any(feature = "std", feature = "alloc"))]
impl<M: 'static> HKT for TracedF<M> {
type Of<T> = Box<dyn Fn(M) -> T>;
}