diff --git a/src/func/classes/lazy.rs b/src/func/classes/lazy.rs index b0dde7e..9120e6a 100644 --- a/src/func/classes/lazy.rs +++ b/src/func/classes/lazy.rs @@ -7,6 +7,8 @@ //! //! For stackless execution see [`super::stackless`]. +use std::{cell::RefCell, rc::Rc}; + use crate::func::*; pub struct LazyClass; @@ -104,3 +106,32 @@ impl Monad for LazyClass { Box::new(|| ffa()()) } } + +fn unshare<'a, A: 'a + Clone>(shared: &mut Option A>>) -> A { + let a = shared.take().expect( + "cannot evaluate a missing shared lazy value. probably, the shared value depends on itself", + )(); + let cloned = a.clone(); + *shared = Some(Box::new(|| cloned)); + a +} + +impl SharedFunctor for LazyClass { + type Shared<'a, A: 'a + Clone> = Rc A>>>> + where + Self: 'a; + + fn share<'a, A: 'a + Clone>(fa: Self::F<'a, A>) -> Self::Shared<'a, A> + where + Self: 'a, + { + Rc::new(RefCell::new(Some(fa))) + } + + fn unshare<'a, A: 'a + Clone>(sa: Self::Shared<'a, A>) -> Self::F<'a, A> + where + Self: 'a, + { + Box::new(move || unshare(&mut *sa.borrow_mut())) + } +}