#[cfg(feature = "alloc")]
extern crate alloc;
use crate::typeclasses::hkt::{CloneHKT, FunctorHKT, HKT};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NatF<R> {
ZeroF,
SuccF(R),
}
pub struct NatFWitness;
impl HKT for NatFWitness {
type Target<T> = NatF<T>;
}
impl FunctorHKT for NatFWitness {
#[inline]
fn map<A, B, F>(fa: NatF<A>, mut f: F) -> NatF<B>
where
F: FnMut(A) -> B,
{
match fa {
NatF::ZeroF => NatF::ZeroF,
NatF::SuccF(a) => NatF::SuccF(f(a)),
}
}
}
impl CloneHKT for NatFWitness {
#[inline]
fn clone_hkt<T: Clone>(t: &NatF<T>) -> NatF<T> {
match t {
NatF::ZeroF => NatF::ZeroF,
NatF::SuccF(a) => NatF::SuccF(a.clone()),
}
}
}
impl<R> NatF<R> {
#[inline]
pub fn map<B, F>(self, f: F) -> NatF<B>
where
F: FnOnce(R) -> B,
{
match self {
NatF::ZeroF => NatF::ZeroF,
NatF::SuccF(r) => NatF::SuccF(f(r)),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ListF<A, R> {
NilF,
ConsF(A, R),
}
pub struct ListFWitness<A>(core::marker::PhantomData<A>);
impl<A> HKT for ListFWitness<A> {
type Target<T> = ListF<A, T>;
}
impl<A: Clone> FunctorHKT for ListFWitness<A> {
#[inline]
fn map<R1, R2, F>(fa: ListF<A, R1>, mut f: F) -> ListF<A, R2>
where
F: FnMut(R1) -> R2,
{
match fa {
ListF::NilF => ListF::NilF,
ListF::ConsF(a, r) => ListF::ConsF(a, f(r)),
}
}
}
impl<A: Clone> CloneHKT for ListFWitness<A> {
#[inline]
fn clone_hkt<T: Clone>(t: &ListF<A, T>) -> ListF<A, T> {
match t {
ListF::NilF => ListF::NilF,
ListF::ConsF(a, r) => ListF::ConsF(a.clone(), r.clone()),
}
}
}
impl<A, R> ListF<A, R> {
#[inline]
pub fn map_rec<B, F>(self, f: F) -> ListF<A, B>
where
F: FnOnce(R) -> B,
{
match self {
ListF::NilF => ListF::NilF,
ListF::ConsF(a, r) => ListF::ConsF(a, f(r)),
}
}
#[inline]
pub fn map_elem<B, F>(self, f: F) -> ListF<B, R>
where
F: FnOnce(A) -> B,
{
match self {
ListF::NilF => ListF::NilF,
ListF::ConsF(a, r) => ListF::ConsF(f(a), r),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TreeF<A, R> {
EmptyF,
NodeF(A, R, R),
}
pub struct TreeFWitness<A>(core::marker::PhantomData<A>);
impl<A> HKT for TreeFWitness<A> {
type Target<T> = TreeF<A, T>;
}
impl<A: Clone> FunctorHKT for TreeFWitness<A> {
#[inline]
fn map<R1, R2, F>(fa: TreeF<A, R1>, mut f: F) -> TreeF<A, R2>
where
F: FnMut(R1) -> R2,
{
match fa {
TreeF::EmptyF => TreeF::EmptyF,
TreeF::NodeF(a, l, r) => TreeF::NodeF(a, f(l), f(r)),
}
}
}
impl<A: Clone> CloneHKT for TreeFWitness<A> {
#[inline]
fn clone_hkt<T: Clone>(t: &TreeF<A, T>) -> TreeF<A, T> {
match t {
TreeF::EmptyF => TreeF::EmptyF,
TreeF::NodeF(a, l, r) => TreeF::NodeF(a.clone(), l.clone(), r.clone()),
}
}
}
impl<A, R> TreeF<A, R> {
#[inline]
pub fn map_rec<B, F>(self, mut f: F) -> TreeF<A, B>
where
F: FnMut(R) -> B,
{
match self {
TreeF::EmptyF => TreeF::EmptyF,
TreeF::NodeF(a, l, r) => TreeF::NodeF(a, f(l), f(r)),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MaybeF<A, R> {
NothingF,
JustF(A, R),
}
pub struct MaybeFWitness<A>(core::marker::PhantomData<A>);
impl<A> HKT for MaybeFWitness<A> {
type Target<T> = MaybeF<A, T>;
}
impl<A: Clone> FunctorHKT for MaybeFWitness<A> {
#[inline]
fn map<R1, R2, F>(fa: MaybeF<A, R1>, mut f: F) -> MaybeF<A, R2>
where
F: FnMut(R1) -> R2,
{
match fa {
MaybeF::NothingF => MaybeF::NothingF,
MaybeF::JustF(a, r) => MaybeF::JustF(a, f(r)),
}
}
}
impl<A: Clone> CloneHKT for MaybeFWitness<A> {
#[inline]
fn clone_hkt<T: Clone>(t: &MaybeF<A, T>) -> MaybeF<A, T> {
match t {
MaybeF::NothingF => MaybeF::NothingF,
MaybeF::JustF(a, r) => MaybeF::JustF(a.clone(), r.clone()),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ExprF<R> {
LitF(i64),
AddF(R, R),
MulF(R, R),
NegF(R),
}
pub struct ExprFWitness;
impl HKT for ExprFWitness {
type Target<T> = ExprF<T>;
}
impl FunctorHKT for ExprFWitness {
#[inline]
fn map<A, B, F>(fa: ExprF<A>, mut f: F) -> ExprF<B>
where
F: FnMut(A) -> B,
{
match fa {
ExprF::LitF(n) => ExprF::LitF(n),
ExprF::AddF(l, r) => ExprF::AddF(f(l), f(r)),
ExprF::MulF(l, r) => ExprF::MulF(f(l), f(r)),
ExprF::NegF(e) => ExprF::NegF(f(e)),
}
}
}
impl CloneHKT for ExprFWitness {
#[inline]
fn clone_hkt<T: Clone>(t: &ExprF<T>) -> ExprF<T> {
match t {
ExprF::LitF(n) => ExprF::LitF(*n),
ExprF::AddF(l, r) => ExprF::AddF(l.clone(), r.clone()),
ExprF::MulF(l, r) => ExprF::MulF(l.clone(), r.clone()),
ExprF::NegF(e) => ExprF::NegF(e.clone()),
}
}
}
impl<R> ExprF<R> {
#[inline]
pub fn map<B, F>(self, mut f: F) -> ExprF<B>
where
F: FnMut(R) -> B,
{
match self {
ExprF::LitF(n) => ExprF::LitF(n),
ExprF::AddF(l, r) => ExprF::AddF(f(l), f(r)),
ExprF::MulF(l, r) => ExprF::MulF(f(l), f(r)),
ExprF::NegF(e) => ExprF::NegF(f(e)),
}
}
}
#[cfg(feature = "alloc")]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RoseF<A, R> {
pub value: A,
pub children: alloc::vec::Vec<R>,
}
#[cfg(feature = "alloc")]
pub struct RoseFWitness<A>(core::marker::PhantomData<A>);
#[cfg(feature = "alloc")]
impl<A> HKT for RoseFWitness<A> {
type Target<T> = RoseF<A, T>;
}
#[cfg(feature = "alloc")]
impl<A: Clone> FunctorHKT for RoseFWitness<A> {
#[inline]
fn map<R1, R2, F>(fa: RoseF<A, R1>, mut f: F) -> RoseF<A, R2>
where
F: FnMut(R1) -> R2,
{
RoseF {
value: fa.value,
children: fa.children.into_iter().map(&mut f).collect(),
}
}
}
#[cfg(feature = "alloc")]
impl<A: Clone> CloneHKT for RoseFWitness<A> {
#[inline]
fn clone_hkt<T: Clone>(t: &RoseF<A, T>) -> RoseF<A, T> {
RoseF {
value: t.value.clone(),
children: t.children.clone(),
}
}
}
#[cfg(feature = "alloc")]
impl<A, R> RoseF<A, R> {
#[inline]
pub fn new(value: A, children: alloc::vec::Vec<R>) -> Self {
RoseF { value, children }
}
#[inline]
pub fn leaf(value: A) -> Self {
RoseF {
value,
children: alloc::vec::Vec::new(),
}
}
#[inline]
pub fn map_rec<B, F>(self, mut f: F) -> RoseF<A, B>
where
F: FnMut(R) -> B,
{
RoseF {
value: self.value,
children: self.children.into_iter().map(&mut f).collect(),
}
}
}