diff --git a/src/func.rs b/src/func.rs index 41a38a0..1769e26 100644 --- a/src/func.rs +++ b/src/func.rs @@ -257,3 +257,17 @@ pub trait MonadFailOver: MonadFailAny { Self: 'a, T: 'a; } + +pub trait SharedFunctor: WeakFunctor { + type Shared<'a, A: 'a + Clone>: 'a + Clone + where + Self: 'a; + + fn share<'a, A: 'a + Clone>(fa: Self::F<'a, A>) -> Self::Shared<'a, A> + where + Self: 'a; + + fn unshare<'a, A: 'a + Clone>(sa: Self::Shared<'a, A>) -> Self::F<'a, A> + where + Self: 'a; +} diff --git a/src/func/classes/composition.rs b/src/func/classes/composition.rs index 54d9683..8ae9645 100644 --- a/src/func/classes/composition.rs +++ b/src/func/classes/composition.rs @@ -124,7 +124,8 @@ impl Monad for CompositionClass { impl + LocalFunctor> MonadFail for CompositionClass { fn fail<'a, A: 'a>(e: E) -> Self::F<'a, A> where - Self: 'a { + Self: 'a, + { U::pure(V::fail(e)) } } diff --git a/src/func/classes/future.rs b/src/func/classes/future.rs index 907ab6d..ffe43de 100644 --- a/src/func/classes/future.rs +++ b/src/func/classes/future.rs @@ -5,7 +5,7 @@ use std::{future::Future, pin::Pin}; -use futures::join; +use futures::{future::Shared, join, FutureExt}; use crate::func::*; @@ -107,3 +107,23 @@ impl Monad for FutureClass { Box::pin(async { ffa.await.await }) } } + +impl SharedFunctor for FutureClass { + type Shared<'a, A: 'a + Clone> = Shared>>> + where + Self: 'a; + + fn share<'a, A: 'a + Clone>(fa: Self::F<'a, A>) -> Self::Shared<'a, A> + where + Self: 'a, + { + fa.shared() + } + + fn unshare<'a, A: 'a + Clone>(sa: Self::Shared<'a, A>) -> Self::F<'a, A> + where + Self: 'a, + { + Box::pin(sa) + } +} diff --git a/src/func/classes/option.rs b/src/func/classes/option.rs index 7758b95..a379ae4 100644 --- a/src/func/classes/option.rs +++ b/src/func/classes/option.rs @@ -175,3 +175,23 @@ mod option_tests { test_suite::monad_follows_laws::().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 + } +} diff --git a/src/func/classes/result.rs b/src/func/classes/result.rs index 854c407..e8bd56b 100644 --- a/src/func/classes/result.rs +++ b/src/func/classes/result.rs @@ -213,3 +213,23 @@ impl MonadFailOver for ResultFailOver { fa } } + +impl SharedFunctor for ResultClass { + 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 + } +} diff --git a/src/func/classes/solo.rs b/src/func/classes/solo.rs index a3989bc..dfaf8e7 100644 --- a/src/func/classes/solo.rs +++ b/src/func/classes/solo.rs @@ -114,3 +114,23 @@ impl LocalFunctor for SoloClass { 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 + } +} diff --git a/src/std.rs b/src/std.rs index 30fa0ac..4c517cb 100644 --- a/src/std.rs +++ b/src/std.rs @@ -37,7 +37,7 @@ impl ExtSerializable for S { } /// Extention trait for simpler conversion between [`Context::T`] and [`Context::Fallible`]. -/// +/// /// Until either Rust type system or [`crate::func`] take serious changes, /// this is the preferred way to switch between [Wrapped] and [fallible]. pub trait FallibleContext: Context { diff --git a/src/std/atomic/boolean.rs b/src/std/atomic/boolean.rs index 019e01e..3b590e4 100644 --- a/src/std/atomic/boolean.rs +++ b/src/std/atomic/boolean.rs @@ -80,8 +80,14 @@ mod tests { #[test] fn cannot_parse_out_of_bound_value() { - assert_eq!(bool::parse_slice(&[2]).unwrap_err(), BooleanParseError::OutOfBounds(2)); - assert_eq!(bool::parse_slice(&[2, 0]).unwrap_err(), BooleanParseError::OutOfBounds(2)); + assert_eq!( + bool::parse_slice(&[2]).unwrap_err(), + BooleanParseError::OutOfBounds(2) + ); + assert_eq!( + bool::parse_slice(&[2, 0]).unwrap_err(), + BooleanParseError::OutOfBounds(2) + ); } #[test] @@ -91,6 +97,9 @@ mod tests { #[test] fn cannot_parse_extra_tail() { - assert_eq!(bool::parse_slice(&[0, 10, 20, 30]).unwrap_err(), BooleanParseError::ExtraData(3)); + assert_eq!( + bool::parse_slice(&[0, 10, 20, 30]).unwrap_err(), + BooleanParseError::ExtraData(3) + ); } } diff --git a/src/std/collections/rbtree.rs b/src/std/collections/rbtree.rs index 3648ddb..67f0a34 100644 --- a/src/std/collections/rbtree.rs +++ b/src/std/collections/rbtree.rs @@ -1,6 +1,6 @@ pub mod subset; -use std::{rc::Rc, error::Error, fmt::Display}; +use std::{error::Error, fmt::Display, rc::Rc}; use crate::core::*; use crate::std::{ @@ -224,7 +224,8 @@ impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> Factory<'a, Ctx> for BFactory> Factory<'a, Ctx> for RFactory