derive(SharedFunctor)

This commit is contained in:
AF 2023-04-25 14:32:50 +00:00
parent 21edad6c75
commit 68bce93ede
7 changed files with 64 additions and 60 deletions

View File

@ -3,11 +3,18 @@ name = "radn-rs"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
[workspace]
members = [
"radn-derive",
]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
futures = "0.3.26" futures = "0.3.26"
hex = "0.4.3" hex = "0.4.3"
radn-derive = { path = "radn-derive" }
[dev-dependencies] [dev-dependencies]
sha2 = "0.10.6" sha2 = "0.10.6"

12
radn-derive/Cargo.toml Normal file
View File

@ -0,0 +1,12 @@
[package]
name = "radn-derive"
version = "0.1.0"
edition = "2021"
[lib]
proc-macro = true
[dependencies]
# proc-macro2 = "1"
quote = "1"
syn = "2"

41
radn-derive/src/lib.rs Normal file
View File

@ -0,0 +1,41 @@
use quote::quote;
use syn::{parse_macro_input, parse_quote, DeriveInput, GenericParam, Generics};
#[proc_macro_derive(SharedFunctor)]
pub fn derive_shared_functor(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let name = input.ident;
let generics = add_trait_bounds(input.generics);
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
let expanded = quote! {
impl #impl_generics SharedFunctor for #name #ty_generics #where_clause {
type Shared<'a, A: 'a + Clone> = Self::F<'a, A>
where
Self: 'a;
fn share<'a, A: 'a + Clone>(fa: Self::F<'a, A>) -> Self::Shared<'a, A>
where
Self: 'a,
{
fa
}
fn unshare<'a, A: 'a + Clone>(sa: Self::Shared<'a, A>) -> Self::F<'a, A>
where
Self: 'a,
{
sa
}
}
};
proc_macro::TokenStream::from(expanded)
}
fn add_trait_bounds(mut generics: Generics) -> Generics {
for param in &mut generics.params {
if let GenericParam::Type(ref mut type_param) = *param {
type_param.bounds.push(parse_quote!(Clone));
}
}
generics
}

View File

@ -19,6 +19,7 @@ pub mod tests;
pub use self::istate::IState; pub use self::istate::IState;
use self::istate::IStateClass; use self::istate::IStateClass;
pub use radn_derive::SharedFunctor;
/// Part of Haskell's `Functor f` responsible to use `f a`. /// Part of Haskell's `Functor f` responsible to use `f a`.
/// ///

View File

@ -9,6 +9,7 @@
use crate::func::*; use crate::func::*;
#[derive(SharedFunctor)]
pub struct OptionClass; pub struct OptionClass;
impl WeakFunctor for OptionClass { impl WeakFunctor for OptionClass {
@ -175,23 +176,3 @@ mod option_tests {
test_suite::monad_follows_laws::<T>().unwrap(); test_suite::monad_follows_laws::<T>().unwrap();
} }
} }
impl SharedFunctor for OptionClass {
type Shared<'a, A: 'a + Clone> = Self::F<'a, A>
where
Self: 'a;
fn share<'a, A: 'a + Clone>(fa: Self::F<'a, A>) -> Self::Shared<'a, A>
where
Self: 'a,
{
fa
}
fn unshare<'a, A: 'a + Clone>(sa: Self::Shared<'a, A>) -> Self::F<'a, A>
where
Self: 'a,
{
sa
}
}

View File

@ -9,6 +9,7 @@
use crate::func::*; use crate::func::*;
#[derive(SharedFunctor)]
pub struct ResultClass<E>(E); pub struct ResultClass<E>(E);
impl<E> WeakFunctor for ResultClass<E> { impl<E> WeakFunctor for ResultClass<E> {
@ -213,23 +214,3 @@ impl<T: Monad> MonadFailOver<T> for ResultFailOver<T> {
fa fa
} }
} }
impl<E: Clone> SharedFunctor for ResultClass<E> {
type Shared<'a, A: 'a + Clone> = Self::F<'a, A>
where
Self: 'a;
fn share<'a, A: 'a + Clone>(fa: Self::F<'a, A>) -> Self::Shared<'a, A>
where
Self: 'a,
{
fa
}
fn unshare<'a, A: 'a + Clone>(sa: Self::Shared<'a, A>) -> Self::F<'a, A>
where
Self: 'a,
{
sa
}
}

View File

@ -4,6 +4,7 @@
use crate::func::*; use crate::func::*;
#[derive(SharedFunctor)]
pub struct SoloClass; pub struct SoloClass;
impl WeakFunctor for SoloClass { impl WeakFunctor for SoloClass {
@ -114,23 +115,3 @@ impl LocalFunctor for SoloClass {
fa fa
} }
} }
impl SharedFunctor for SoloClass {
type Shared<'a, A: 'a + Clone> = Self::F<'a, A>
where
Self: 'a;
fn share<'a, A: 'a + Clone>(fa: Self::F<'a, A>) -> Self::Shared<'a, A>
where
Self: 'a,
{
fa
}
fn unshare<'a, A: 'a + Clone>(sa: Self::Shared<'a, A>) -> Self::F<'a, A>
where
Self: 'a,
{
sa
}
}