diff --git a/src/core/functions.rs b/src/core/functions.rs index 5e72acc..daec578 100644 --- a/src/core/functions.rs +++ b/src/core/functions.rs @@ -4,5 +4,19 @@ * Copyright (c) 2023 Didier Plaindoux */ -pub type Fun = Box B>; -pub type FunOnce<'a, A, B> = Box B + 'a>; +pub fn uncurry<'a, A, B, C, CURRY>(f: CURRY) -> Box C + 'a> +where + CURRY: Fn(A) -> Box C> + 'a, +{ + Box::new(move |a, b| f(a)(b)) +} + +pub fn curry<'a, A, B, C, UNCURRY>( + f: UNCURRY, +) -> Box Box C + 'a> + 'a> +where + A: 'a, + UNCURRY: FnOnce(A, B) -> C + 'a, +{ + Box::new(move |a| Box::new(move |b| f(a, b))) +} diff --git a/src/core/mod.rs b/src/core/mod.rs index 225a108..fd05481 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -7,3 +7,4 @@ pub mod functions; pub mod hkp; pub mod transform; +pub mod types; diff --git a/src/core/types.rs b/src/core/types.rs new file mode 100644 index 0000000..c1cb872 --- /dev/null +++ b/src/core/types.rs @@ -0,0 +1,10 @@ +/* + * MIT License + * + * Copyright (c) 2023 Didier Plaindoux + */ + +pub type Fun = Box B>; +pub type FunLT<'a, A, B> = Box B + 'a>; +pub type FunOnce = Box B>; +pub type FunOnceLT<'a, A, B> = Box B + 'a>; diff --git a/src/specs/applicative.rs b/src/specs/applicative.rs index 1dae662..6121b30 100644 --- a/src/specs/applicative.rs +++ b/src/specs/applicative.rs @@ -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> { @@ -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(mf: Self::T) -> FunOnce<'a, Self::T, Self::T> + fn apply(mf: Self::T) -> FunOnceLT<'a, Self::T, Self::T> where Self: 'a, A: Clone, @@ -42,13 +42,13 @@ pub mod curry { Box::new(move |ma| >::apply(mf, ma)) } - fn lift1(f: Fun) -> FunOnce<'a, Self::T, Self::T> { + fn lift1(f: Fun) -> FunOnceLT<'a, Self::T, Self::T> { Box::new(move |ma| >::lift1(f, ma)) } fn lift2( f: Fun>, - ) -> FunOnce<'a, Self::T, FunOnce<'a, Self::T, Self::T>> + ) -> FunOnceLT<'a, Self::T, FunOnceLT<'a, Self::T, Self::T>> where Self: 'a, A: Clone, diff --git a/src/specs/bind.rs b/src/specs/bind.rs index 9ce0ac7..1d49937 100644 --- a/src/specs/bind.rs +++ b/src/specs/bind.rs @@ -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(ma: Self::T) -> FunOnce<'a, BIND, Self::T> + fn bind(ma: Self::T) -> FunOnceLT<'a, BIND, Self::T> where Self: 'a, BIND: Fn(A) -> Self::T + 'a, diff --git a/src/specs/functor.rs b/src/specs/functor.rs index cb5643d..ab0ac2a 100644 --- a/src/specs/functor.rs +++ b/src/specs/functor.rs @@ -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(f: MAP) -> Box) -> Self::T + 'a> where + Self: 'a, + A: Copy, MAP: Fn(A) -> B + 'a, { - Box::new(move |a| >::map(f, a)) + curry(>::map)(f) } } } diff --git a/src/standard/reader.rs b/src/standard/reader.rs index 4de8249..3db8621 100644 --- a/src/standard/reader.rs +++ b/src/standard/reader.rs @@ -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>, PhantomData); +pub struct Reader<'a, E, F: HKP<'a>, A: 'a>(FunOnceLT<'a, E, F::T>, PhantomData); pub struct ReaderK<'a, E, F: HKP<'a>>(PhantomData<&'a E>, PhantomData);