Skip to content

Commit

Permalink
Deep code review introducing lifetime required for Reader, Writer etc.
Browse files Browse the repository at this point in the history
  • Loading branch information
d-plaindoux committed Sep 15, 2023
1 parent 58964c0 commit 2c51b7a
Show file tree
Hide file tree
Showing 17 changed files with 228 additions and 193 deletions.
4 changes: 2 additions & 2 deletions src/core/hkp.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
pub trait HKP {
type T<A>;
pub trait HKP<'a> {
type T<A: 'a>;
}
10 changes: 5 additions & 5 deletions src/core/transform.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use crate::core::hkp::HKP;

pub trait Transform<A>: HKP {
type This: HKP;
pub trait Transform<'a, A>: HKP<'a> {
type This: HKP<'a>;

fn from_hkp<B>(a: <Self::This as HKP>::T<B>) -> Self::T<B>;
fn from_hkp<B>(a: <Self::This as HKP<'a>>::T<B>) -> Self::T<B>;

fn from_self<B>(a: Self::T<B>) -> <Self::This as HKP>::T<B>;
fn from_self<B>(a: Self::T<B>) -> <Self::This as HKP<'a>>::T<B>;

fn to_hkp(self) -> <Self::This as HKP>::T<A>;
fn to_hkp(self) -> <Self::This as HKP<'a>>::T<A>;
}
24 changes: 13 additions & 11 deletions src/specs/applicative.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
use crate::specs::functor::Functor;

pub trait Applicative: Functor {
pub trait Applicative<'a>: Functor<'a> {
fn pure<A>(a: A) -> Self::T<A>;

fn apply<A, B, MAP>(mf: Self::T<MAP>, ma: Self::T<A>) -> Self::T<B>
where
A: Clone,
MAP: Fn(A) -> B;
where
A: Clone,
MAP: Fn(A) -> B;
}

pub mod infix {
use crate::core::transform::Transform;
use crate::specs::applicative::Applicative as Api;

pub trait Applicative<A>: Transform<A, T<A>=Self::TL<A>, This=Self::ThisL> {
type ThisL: Api;
type TL<B>: Applicative<B>;
pub trait Applicative<'a, A: 'a>:
Transform<'a, A, T<A> = Self::TL<A>, This = Self::ThisL>
{
type ThisL: Api<'a>;
type TL<B: 'a>: Applicative<'a, B>;

fn pure<B>(a: B) -> Self::T<B> {
Self::from_hkp(Self::This::pure(a))
}

fn apply<B, MAP>(self, mf: Self::T<MAP>) -> Self::T<B>
where
A: Clone,
MAP: Fn(A) -> B,
Self: Sized,
where
A: Clone,
MAP: Fn(A) -> B,
Self: Sized,
{
Self::from_hkp(Self::This::apply(Self::from_self::<MAP>(mf), self.to_hkp()))
}
Expand Down
17 changes: 10 additions & 7 deletions src/specs/bind.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use crate::specs::applicative::Applicative;

pub trait Bind: Applicative {
pub trait Bind<'a>: Applicative<'a>
where
Self: 'a,
{
fn join<A>(mma: Self::T<Self::T<A>>) -> Self::T<A>;

fn bind<A, B, BIND>(ma: Self::T<A>, mf: BIND) -> Self::T<B>
where
BIND: Fn(A) -> Self::T<B>,
BIND: Fn(A) -> Self::T<B> + 'a,
{
Self::join(Self::map(mf, ma))
}
Expand All @@ -15,9 +18,9 @@ pub mod infix {
use crate::core::transform::Transform;
use crate::specs::bind::Bind as Api;

pub trait Bind<A>: Transform<A, T<A> = Self::TL<A>, This = Self::ThisL> {
type ThisL: Api;
type TL<B>: Bind<B>;
pub trait Bind<'a, A: 'a>: Transform<'a, A, T<A> = Self::TL<A>, This = Self::ThisL> {
type ThisL: Api<'a>;
type TL<B: 'a>: Bind<'a, B>;

fn join<B>(mma: Self::T<Self::T<B>>) -> Self::T<B> {
Self::from_hkp(Self::This::bind(Self::from_self(mma), |a| {
Expand All @@ -27,10 +30,10 @@ pub mod infix {

fn bind<B, BIND>(self, mf: BIND) -> Self::T<B>
where
BIND: Fn(A) -> Self::T<B>,
BIND: Fn(A) -> Self::T<B> + 'a,
Self: Sized,
{
Self::from_hkp(Self::This::bind(self.to_hkp(), |a| {
Self::from_hkp(Self::This::bind(self.to_hkp(), move |a| {
Self::from_self::<B>(mf(a))
}))
}
Expand Down
18 changes: 9 additions & 9 deletions src/specs/functor.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
use crate::core::hkp::HKP;

pub trait Functor: HKP {
pub trait Functor<'a>: HKP<'a> {
fn map<A, B, MAP>(f: MAP, ma: Self::T<A>) -> Self::T<B>
where
MAP: Fn(A) -> B;
where
MAP: Fn(A) -> B + 'a;
}

pub mod infix {
use crate::core::transform::Transform;
use crate::specs::functor::Functor as Api;

pub trait Functor<A>: Transform<A, T<A>=Self::TL<A>, This=Self::ThisL> {
type ThisL: Api;
type TL<B>: Functor<B>;
pub trait Functor<'a, A: 'a>: Transform<'a, A, T<A> = Self::TL<A>, This = Self::ThisL> {
type ThisL: Api<'a>;
type TL<B: 'a>: Functor<'a, B>;

fn map<B, MAP>(self, f: MAP) -> Self::T<B>
where
MAP: Fn(A) -> B,
Self: Sized,
where
MAP: Fn(A) -> B + 'a,
Self: Sized,
{
Self::from_hkp(Self::This::map(f, self.to_hkp()))
}
Expand Down
12 changes: 6 additions & 6 deletions src/specs/monad.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::specs::bind::Bind;

pub trait Monad: Bind {
pub trait Monad<'a>: Bind<'a> {
fn returns<A>(a: A) -> Self::T<A> {
Self::pure(a)
}
Expand All @@ -11,10 +11,10 @@ pub mod infix {
use crate::specs::bind::Bind;
use crate::specs::monad::Monad as Api;

pub trait Monad<A>: Transform<A, T<A> = Self::TL<A>, This = Self::ThisL> {
type ThisL: Api;
pub trait Monad<'a, A: 'a>: Transform<'a, A, T<A> = Self::TL<A>, This = Self::ThisL> {
type ThisL: Api<'a>;

type TL<B>: Monad<B>;
type TL<B: 'a>: Monad<'a, B>;

fn returns<B>(b: B) -> Self::T<B> {
Self::from_hkp(Self::This::returns(b))
Expand All @@ -28,10 +28,10 @@ pub mod infix {

fn bind<B, BIND>(self, mf: BIND) -> Self::T<B>
where
BIND: Fn(A) -> Self::T<B>,
BIND: Fn(A) -> Self::T<B> + 'a,
Self: Sized,
{
Self::from_hkp(<Self::This as Bind>::bind(self.to_hkp(), |a| {
Self::from_hkp(<Self::This as Bind>::bind(self.to_hkp(), move |a| {
Self::from_self::<B>(mf(a))
}))
}
Expand Down
52 changes: 26 additions & 26 deletions src/standard/either.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ pub enum Either<L, R> {
Right(R),
}

impl<L> HKP for EitherK<L> {
type T<R> = Either<L, R>;
impl<'a, L> HKP<'a> for EitherK<L> {
type T<R: 'a> = Either<L, R>;
}

impl<E> Functor for EitherK<E> {
fn map<A, B, MAP>(f: MAP, ma: Self::T<A>) -> Self::T<B>
impl<'a, E> Functor<'a> for EitherK<E> {
fn map<A: 'a, B: 'a, MAP>(f: MAP, ma: Self::T<A>) -> Self::T<B>
where
MAP: Fn(A) -> B,
MAP: Fn(A) -> B + 'a,
{
match ma {
Left(l) => Left(l),
Expand All @@ -32,14 +32,14 @@ impl<E> Functor for EitherK<E> {
}
}

impl<E> Applicative for EitherK<E> {
fn pure<A>(a: A) -> Self::T<A> {
impl<'a, E> Applicative<'a> for EitherK<E> {
fn pure<A: 'a>(a: A) -> Self::T<A> {
Right(a)
}

fn apply<A, B, MAP>(mf: Self::T<MAP>, ma: Self::T<A>) -> Self::T<B>
fn apply<A: 'a, B: 'a, MAP>(mf: Self::T<MAP>, ma: Self::T<A>) -> Self::T<B>
where
MAP: Fn(A) -> B,
MAP: Fn(A) -> B + 'a,
{
match mf {
Left(l) => Left(l),
Expand All @@ -48,16 +48,16 @@ impl<E> Applicative for EitherK<E> {
}
}

impl<E> Bind for EitherK<E> {
fn join<A>(mma: Self::T<Self::T<A>>) -> Self::T<A> {
impl<'a, E: 'a> Bind<'a> for EitherK<E> {
fn join<A: 'a>(mma: Self::T<Self::T<A>>) -> Self::T<A> {
match mma {
Left(ma) => Left(ma),
Right(r) => r,
}
}
}

impl<E> Monad for EitherK<E> {}
impl<'a, E: 'a> Monad<'a> for EitherK<E> {}

mod infix {
use crate::core::hkp::HKP;
Expand All @@ -68,43 +68,43 @@ mod infix {
use crate::specs::monad::infix::Monad;
use crate::standard::either::{Either, EitherK};

impl<L, R> HKP for Either<L, R> {
type T<B> = Either<L, B>;
impl<'a, L, R> HKP<'a> for Either<L, R> {
type T<B: 'a> = Either<L, B>;
}

impl<L, R> Transform<R> for Either<L, R> {
impl<'a, L, R: 'a> Transform<'a, R> for Either<L, R> {
type This = EitherK<L>;

fn from_hkp<B>(a: <Self::This as HKP>::T<B>) -> Self::T<B> {
fn from_hkp<B: 'a>(a: <Self::This as HKP<'a>>::T<B>) -> Self::T<B> {
a
}

fn from_self<B>(a: Self::T<B>) -> <Self::This as HKP>::T<B> {
fn from_self<B: 'a>(a: Self::T<B>) -> <Self::This as HKP<'a>>::T<B> {
a
}

fn to_hkp(self) -> <Self::This as HKP>::T<R> {
fn to_hkp(self) -> <Self::This as HKP<'a>>::T<R> {
self
}
}

impl<L, R> Functor<R> for Either<L, R> {
impl<'a, L, R: 'a> Functor<'a, R> for Either<L, R> {
type ThisL = EitherK<L>;
type TL<B> = Either<L, B>;
type TL<B: 'a> = Either<L, B>;
}

impl<L, R> Applicative<R> for Either<L, R> {
impl<'a, L, R: 'a> Applicative<'a, R> for Either<L, R> {
type ThisL = EitherK<L>;
type TL<B> = Either<L, B>;
type TL<B: 'a> = Either<L, B>;
}

impl<L, R> Bind<R> for Either<L, R> {
impl<'a, L: 'a, R: 'a> Bind<'a, R> for Either<L, R> {
type ThisL = EitherK<L>;
type TL<B> = Either<L, B>;
type TL<B: 'a> = Either<L, B>;
}

impl<L, R> Monad<R> for Either<L, R> {
impl<'a, L: 'a, R: 'a> Monad<'a, R> for Either<L, R> {
type ThisL = EitherK<L>;
type TL<B> = Either<L, B>;
type TL<B: 'a> = Either<L, B>;
}
}
Loading

0 comments on commit 2c51b7a

Please sign in to comment.