Skip to content

Commit

Permalink
Use curry/uncurry functions
Browse files Browse the repository at this point in the history
  • Loading branch information
d-plaindoux committed Sep 18, 2023
1 parent cc1bf07 commit f767a77
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 12 deletions.
18 changes: 16 additions & 2 deletions src/core/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,19 @@
* Copyright (c) 2023 Didier Plaindoux
*/

pub type Fun<A, B> = Box<dyn Fn(A) -> B>;
pub type FunOnce<'a, A, B> = Box<dyn FnOnce(A) -> B + 'a>;
pub fn uncurry<'a, A, B, C, CURRY>(f: CURRY) -> Box<dyn Fn(A, B) -> C + 'a>
where
CURRY: Fn(A) -> Box<dyn Fn(B) -> C> + 'a,
{
Box::new(move |a, b| f(a)(b))
}

pub fn curry<'a, A, B, C, UNCURRY>(
f: UNCURRY,
) -> Box<dyn FnOnce(A) -> Box<dyn FnOnce(B) -> C + 'a> + 'a>
where
A: 'a,
UNCURRY: FnOnce(A, B) -> C + 'a,
{
Box::new(move |a| Box::new(move |b| f(a, b)))
}
1 change: 1 addition & 0 deletions src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
pub mod functions;
pub mod hkp;
pub mod transform;
pub mod types;
10 changes: 10 additions & 0 deletions src/core/types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* MIT License
*
* Copyright (c) 2023 Didier Plaindoux
*/

pub type Fun<A, B> = Box<dyn Fn(A) -> B>;
pub type FunLT<'a, A, B> = Box<dyn Fn(A) -> B + 'a>;
pub type FunOnce<A, B> = Box<dyn FnOnce(A) -> B>;
pub type FunOnceLT<'a, A, B> = Box<dyn FnOnce(A) -> B + 'a>;
10 changes: 5 additions & 5 deletions src/specs/applicative.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Copyright (c) 2023 Didier Plaindoux
*/

use crate::core::functions::Fun;
use crate::core::types::Fun;
use crate::specs::functor::Functor;

pub trait Applicative<'a>: Functor<'a> {
Expand All @@ -29,11 +29,11 @@ pub trait Applicative<'a>: Functor<'a> {
}

pub mod curry {
use crate::core::functions::{Fun, FunOnce};
use crate::core::types::{Fun, FunOnceLT};
use crate::specs::applicative::Applicative as Api;

pub trait Applicative<'a>: Api<'a> {
fn apply<A, B, MAP>(mf: Self::T<MAP>) -> FunOnce<'a, Self::T<A>, Self::T<B>>
fn apply<A, B, MAP>(mf: Self::T<MAP>) -> FunOnceLT<'a, Self::T<A>, Self::T<B>>
where
Self: 'a,
A: Clone,
Expand All @@ -42,13 +42,13 @@ pub mod curry {
Box::new(move |ma| <Self as Api<'a>>::apply(mf, ma))
}

fn lift1<A, B>(f: Fun<A, B>) -> FunOnce<'a, Self::T<A>, Self::T<B>> {
fn lift1<A, B>(f: Fun<A, B>) -> FunOnceLT<'a, Self::T<A>, Self::T<B>> {
Box::new(move |ma| <Self as Api<'a>>::lift1(f, ma))
}

fn lift2<A, B, C>(
f: Fun<A, Fun<B, C>>,
) -> FunOnce<'a, Self::T<A>, FunOnce<'a, Self::T<B>, Self::T<C>>>
) -> FunOnceLT<'a, Self::T<A>, FunOnceLT<'a, Self::T<B>, Self::T<C>>>
where
Self: 'a,
A: Clone,
Expand Down
4 changes: 2 additions & 2 deletions src/specs/bind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ pub trait Bind<'a>: Applicative<'a> {
}

pub mod curry {
use crate::core::functions::FunOnce;
use crate::core::types::FunOnceLT;
use crate::specs::bind::Bind as Api;

pub trait Bind<'a>: Api<'a> {
fn bind<A, B, BIND>(ma: Self::T<A>) -> FunOnce<'a, BIND, Self::T<B>>
fn bind<A, B, BIND>(ma: Self::T<A>) -> FunOnceLT<'a, BIND, Self::T<B>>
where
Self: 'a,
BIND: Fn(A) -> Self::T<B> + 'a,
Expand Down
5 changes: 4 additions & 1 deletion src/specs/functor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,17 @@ pub trait Functor<'a>: HKP<'a> {
}

pub mod curry {
use crate::core::functions::curry;
use crate::specs::functor::Functor as Api;

pub trait Functor<'a>: Api<'a> {
fn map<A, B, MAP>(f: MAP) -> Box<dyn FnOnce(Self::T<A>) -> Self::T<B> + 'a>
where
Self: 'a,
A: Copy,
MAP: Fn(A) -> B + 'a,
{
Box::new(move |a| <Self as Api<'a>>::map(f, a))
curry(<Self as Api<'a>>::map)(f)
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/standard/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
* Copyright (c) 2023 Didier Plaindoux
*/

use crate::core::functions::FunOnce;
use crate::core::hkp::HKP;
use crate::core::types::FunOnceLT;
use crate::specs::applicative::Applicative;
use crate::specs::bind::Bind;
use crate::specs::functor::Functor;
use crate::specs::monad::Monad;
use std::marker::PhantomData;

pub struct Reader<'a, E, F: HKP<'a>, A: 'a>(FunOnce<'a, E, F::T<A>>, PhantomData<F>);
pub struct Reader<'a, E, F: HKP<'a>, A: 'a>(FunOnceLT<'a, E, F::T<A>>, PhantomData<F>);

pub struct ReaderK<'a, E, F: HKP<'a>>(PhantomData<&'a E>, PhantomData<F>);

Expand Down

0 comments on commit f767a77

Please sign in to comment.