From 59ff3f139143699ee4d6ddda46b3910b9e278809 Mon Sep 17 00:00:00 2001 From: Andreas Grois Date: Mon, 13 Mar 2023 22:46:23 +0100 Subject: Remove dependency on Paste. Turns out, Rust supports nested fn items. Sooo, the helpers can be defined right inside the functions that need them. In other words, there is no need for a separate module. --- Cargo.toml | 3 +- src/lib.rs | 260 +++++++++++++++++++++++++++++-------------------------------- 2 files changed, 125 insertions(+), 138 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4b3dfa4..eddd798 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,5 +10,4 @@ license = "MPL-2.0+" keywords = ["functor", "applicative", "monad", "category-theory", "haskell"] [dependencies] -higher = "0.2" -paste = "1.0" +higher = "0.2" \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 26fb1e1..f4fdaf7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,163 +1,151 @@ pub extern crate higher; -pub use paste::paste; #[macro_export] macro_rules! free { ($v:vis $name:ident<$generic:ident>, $f:ty) => { - $crate::paste! { - #[derive(Clone)] - $v enum $name<$generic> { - Pure($generic), - Free(Box<$f>) + #[derive(Clone)] + $v enum $name<$generic> { + Pure($generic), + Free(Box<$f>) + } + impl<$generic> $name<$generic>{ + $v fn lift_f(command : <$f as $crate::higher::Functor>::Target<$generic>) -> Self{ + use $crate::higher::Functor; + Self::Free(Box::new(command.fmap(|a| Self::Pure(a)))) } - impl<$generic> $name<$generic>{ - $v fn lift_f(command : <$f as $crate::higher::Functor>::Target<$generic>) -> Self{ - use $crate::higher::Functor; - Self::Free(Box::new(command.fmap(|a| Self::Pure(a)))) - } - - $v fn retract<'a>(self) -> <$f as $crate::higher::Bind<'a,Self>>::Target<$generic> where $f : $crate::higher::Monad<'a,Self>, <$f as $crate::higher::Bind<'a,Self>>::Target<$generic> : $crate::higher::Pure<$generic> { - use $crate::higher::{Bind, Pure}; - match self { - $name::Pure(a) => {<$f as $crate::higher::Bind<'a,Self>>::Target::<$generic>::pure(a)}, - $name::Free(m) => {m.bind(|a| a.retract())} - } + + $v fn retract<'a>(self) -> <$f as $crate::higher::Bind<'a,Self>>::Target<$generic> where $f : $crate::higher::Monad<'a,Self>, <$f as $crate::higher::Bind<'a,Self>>::Target<$generic> : $crate::higher::Pure<$generic> { + use $crate::higher::{Bind, Pure}; + match self { + $name::Pure(a) => {<$f as $crate::higher::Bind<'a,Self>>::Target::<$generic>::pure(a)}, + $name::Free(m) => {m.bind(|a| a.retract())} } } - mod [<$name _module>] { - use $crate::higher::{Functor, Apply, Bind, Applicative, Monad, Pure, apply::ApplyFn, apply::ap}; - use super::$name; - impl<$generic> $name<$generic> { - fn __fmap_impl<'a, B, F>(self, f: &F) -> $name where F: Fn($generic) -> B + 'a{ - match self { - $name::Pure(a) => {$name::Pure(f(a))}, - $name::Free(fa) => {$name::Free(Box::new(fa.fmap(|x| x.__fmap_impl(f))))}, - } - } - fn __bind_impl<'a, B, F>(self, f: &F) -> $name where F: Fn($generic) -> $name + 'a{ - match self { - $name::Pure(a) => {f(a)}, - $name::Free(m) => {$name::Free(Box::new(m.fmap(|x| x.__bind_impl(f))))}, - } - } - } - - impl<'a,A> Functor<'a,A> for $name { - type Target = $name; - fn fmap(self, f: F) -> Self::Target where F: Fn(A) -> B + 'a{ - self.__fmap_impl(&f) - } - } - - impl Pure for $name { - fn pure(value : A) -> Self { - Self::Pure(value) - } - } + } - impl<'a, A> Apply<'a, A> for $name where A: 'a + Clone,{ - type Target = $name where T:'a; - fn apply( - self, - f: >::Target>, - ) -> >::Target - where - B: 'a, - { - ap(f,self) + impl<'a,A> $crate::higher::Functor<'a,A> for $name { + type Target = $name; + fn fmap(self, f: F) -> Self::Target where F: Fn(A) -> B + 'a{ + fn __fmap_impl<'a, A, B, F>(s : $name, f: &F) -> $name where F: Fn(A) -> B + 'a{ + use $crate::higher::Functor; + match s { + $name::Pure(a) => {$name::Pure(f(a))}, + $name::Free(fa) => {$name::Free(Box::new(fa.fmap(|x| __fmap_impl(x, f))))}, } } - - impl<'a,A> Bind<'a,A> for $name{ - type Target = $name; - fn bind(self, f: F) -> Self::Target - where - F: Fn(A) -> Self::Target, - { - self.__bind_impl(&f) + __fmap_impl(self, &f) + } + } + + impl $crate::higher::Pure for $name { + fn pure(value : A) -> Self { + Self::Pure(value) + } + } + + impl<'a, A> $crate::higher::Apply<'a, A> for $name where A: 'a + Clone,{ + type Target = $name where T:'a; + fn apply( + self, + f: >::Target<$crate::higher::apply::ApplyFn<'a, A, B>>, + ) -> >::Target + where + B: 'a, + { + $crate::higher::apply::ap(f,self) + } + } + + impl<'a,A> $crate::higher::Bind<'a,A> for $name{ + type Target = $name; + fn bind(self, f: F) -> Self::Target + where + F: Fn(A) -> Self::Target, + { + fn __bind_impl<'a, A, B, F>(s : $name, f: &F) -> $name where F: Fn(A) -> $name + 'a{ + use $crate::higher::Functor; + match s { + $name::Pure(a) => {f(a)}, + $name::Free(fa) => {$name::Free(Box::new(fa.fmap(|x| __bind_impl(x, f))))}, } } + __bind_impl(self, &f) } - } + } }; ($v:vis $name:ident<$a:lifetime, $($other_lifetimes:lifetime,)* $generic:ident>, $f:ty) =>{ - $crate::paste! { - #[derive(Clone)] - $v enum $name<$a, $($other_lifetimes,)* $generic> { - Pure($generic), - Free(Box<$f>) + #[derive(Clone)] + $v enum $name<$a, $($other_lifetimes,)* $generic> { + Pure($generic), + Free(Box<$f>) + } + impl<$a, $($other_lifetimes,)* $generic> $name<$a, $($other_lifetimes,)* $generic> where $generic : $a { + $v fn lift_f(command : <$f as $crate::higher::Functor<$a, Self>>::Target<$generic>) -> Self{ + use $crate::higher::Functor; + Self::Free(Box::new(command.fmap(|a| Self::Pure(a)))) } - impl<$a, $($other_lifetimes,)* $generic> $name<$a, $($other_lifetimes,)* $generic> where $generic : $a { - $v fn lift_f(command : <$f as $crate::higher::Functor<$a, Self>>::Target<$generic>) -> Self{ - use $crate::higher::Functor; - Self::Free(Box::new(command.fmap(|a| Self::Pure(a)))) + + $v fn retract(self) -> <$f as $crate::higher::Bind<$a,Self>>::Target<$generic> where $f : $crate::higher::Monad<$a,Self>, <$f as $crate::higher::Bind<$a,Self>>::Target<$generic> : $crate::higher::Pure<$generic> { + use $crate::higher::{Bind, Pure}; + match self { + $name::Pure(a) => {<$f as $crate::higher::Bind<$a,Self>>::Target::<$generic>::pure(a)}, + $name::Free(m) => {m.bind(|a| a.retract())} } + } + } - $v fn retract(self) -> <$f as $crate::higher::Bind<$a,Self>>::Target<$generic> where $f : $crate::higher::Monad<$a,Self>, <$f as $crate::higher::Bind<$a,Self>>::Target<$generic> : $crate::higher::Pure<$generic> { - use $crate::higher::{Bind, Pure}; - match self { - $name::Pure(a) => {<$f as $crate::higher::Bind<$a,Self>>::Target::<$generic>::pure(a)}, - $name::Free(m) => {m.bind(|a| a.retract())} + impl<$a, $($other_lifetimes,)* A> $crate::higher::Functor<$a,A> for $name<$a, $($other_lifetimes,)*A> where A : $a { + type Target = $name<$a, $($other_lifetimes,)* T>; + fn fmap(self, f: F) -> Self::Target + where F: Fn(A) -> B + $a + { + fn __fmap_impl<$a, $($other_lifetimes,)* A, B, F>(s : $name<$a, $($other_lifetimes,)* A>, f : std::rc::Rc) -> $name<$a, $($other_lifetimes,)* B> where A : $a, F: Fn(A) -> B + $a{ + use $crate::higher::Functor; + match s { + $name::Pure(a) => {$name::Pure(f(a))}, + $name::Free(fa) => {$name::Free(Box::new(fa.fmap(move |x : $name<$a, $($other_lifetimes,)*A>| __fmap_impl(x, f.clone()))))}, } } + + let r = std::rc::Rc::new(f); + __fmap_impl(self, r) } - mod [<$name _module>] { - use $crate::higher::{Functor, Apply, Bind, Applicative, Monad, Pure, apply::ApplyFn, apply::ap}; - use super::$name; - impl<$a, $($other_lifetimes,)* $generic> $name<$a, $($other_lifetimes,)* $generic> where $generic : $a { - fn __fmap_impl(self, f: std::rc::Rc) -> $name<$a, $($other_lifetimes,)* B> where F: Fn($generic) -> B + $a{ - match self { - $name::Pure(a) => {$name::Pure(f(a))}, - $name::Free(fa) => {$name::Free(Box::new(fa.fmap(move |x : Self| x.__fmap_impl(f.clone()))))}, - } - } - fn __bind_impl(self, f: std::rc::Rc) -> $name<$a, $($other_lifetimes,)* B> where F: Fn($generic) -> $name<$a, $($other_lifetimes,)* B> + $a{ - match self { - $name::Pure(a) => {f(a)}, - $name::Free(m) => {$name::Free(Box::new(m.fmap(move |x| x.__bind_impl(f.clone()))))}, - } - } - } - - impl<$a, $($other_lifetimes,)* A> Functor<$a,A> for $name<$a, $($other_lifetimes,)*A> where A : $a { - type Target = $name<$a, $($other_lifetimes,)* T>; - fn fmap(self, f: F) -> Self::Target - where F: Fn(A) -> B + $a - { - let r = std::rc::Rc::new(f); - self.__fmap_impl(r) - } - } - - impl<$a, $($other_lifetimes,)* A> Pure for $name<$a, $($other_lifetimes,)* A> { - fn pure(value : A) -> Self { - Self::Pure(value) - } - } - - impl<$a, $($other_lifetimes,)* A> Apply<$a, A> for $name<$a, $($other_lifetimes,)* A> where A: $a + Clone,{ - type Target = $name<$a, $($other_lifetimes,)* T> where T:$a; - fn apply( - self, - f: >::Target>, - ) -> >::Target - where - B: $a, - { - ap(f,self) - } - } - - impl<$a, $($other_lifetimes,)* A> Bind<$a,A> for $name<$a, $($other_lifetimes,)*A> where A : $a{ - type Target = $name<$a, $($other_lifetimes,)* T>; - fn bind(self, f: F) -> Self::Target - where - F: Fn(A) -> Self::Target + $a, - { - let r = std::rc::Rc::new(f); - self.__bind_impl(r) + } + + impl<$a, $($other_lifetimes,)* A> $crate::higher::Pure for $name<$a, $($other_lifetimes,)* A> { + fn pure(value : A) -> Self { + Self::Pure(value) + } + } + + impl<$a, $($other_lifetimes,)* A> $crate::higher::Apply<$a, A> for $name<$a, $($other_lifetimes,)* A> where A: $a + Clone,{ + type Target = $name<$a, $($other_lifetimes,)* T> where T:$a; + fn apply( + self, + f: >::Target<$crate::higher::apply::ApplyFn<$a, A, B>>, + ) -> >::Target + where + B: $a, + { + $crate::higher::apply::ap(f,self) + } + } + + impl<$a, $($other_lifetimes,)* A> $crate::higher::Bind<$a,A> for $name<$a, $($other_lifetimes,)*A> where A : $a{ + type Target = $name<$a, $($other_lifetimes,)* T>; + fn bind(self, f: F) -> Self::Target + where + F: Fn(A) -> Self::Target + $a, + { + fn __bind_impl<$a, $($other_lifetimes,)* A, B, F>(s : $name<$a, $($other_lifetimes,)*A>, f : std::rc::Rc) -> $name<$a, $($other_lifetimes,)* B> where A : $a, F: Fn(A) -> $name<$a, $($other_lifetimes,)* B> + $a{ + use $crate::higher::Functor; + match s { + $name::Pure(a) => {f(a)}, + $name::Free(fa) => {$name::Free(Box::new(fa.fmap(move |x : $name<$a, $($other_lifetimes,)*A>| __bind_impl(x, f.clone()))))}, } } + let r = std::rc::Rc::new(f); + __bind_impl(self, r) } } }; -- cgit v1.2.3