//! Helper [Monad]s to defer execution until necessary. //! Wrapped value is just a box pointing to the constructor function. //! //! Due to semantical laziness, //! [`LazyInstance::replace`] and [`LazyInstance::discard_first`]/[`LazyInstance::discard_second`] //! actually fully cancel the "unnecessary" computation. //! //! For stackless execution see [`stackless`]. //! //! [`stackless`]: super::stackless use crate::func::class_prelude::*; pub struct LazyInstance; impl WeakFunctorAny for LazyInstance { type FAny<'a, A: 'a + Send> = Box A>; } impl<'a> Functor<'a> for LazyInstance { fn fmap( fa: Self::F, f: impl 'a + Send + FnOnce(A) -> B, ) -> Self::F { Box::new(|| f(fa())) } fn replace(fa: Self::F, b: B) -> Self::F { drop(fa); Box::new(|| b) } fn void(fa: Self::F) -> Self::F<()> { drop(fa); Box::new(|| ()) } } impl<'a> Pure<'a> for LazyInstance { fn pure(a: A) -> Self::F { Box::new(|| a) } } impl<'a> ApplicativeSeq<'a> for LazyInstance { fn seq( ff: Self::F B>, fa: Self::F, ) -> Self::F { Box::new(|| ff()(fa())) } } impl<'a> ApplicativeLA2<'a> for LazyInstance { fn la2( fa: Self::F, fb: Self::F, f: impl 'a + Send + FnOnce(A, B) -> C, ) -> Self::F { Box::new(|| f(fa(), fb())) } } impl<'a> ApplicativeTuple<'a> for LazyInstance { fn tuple((fa, fb): (Self::F, Self::F)) -> Self::F<(A, B)> { Box::new(|| (fa(), fb())) } } impl<'a> ApplicativeSelect<'a> for LazyInstance {} impl<'a> Applicative<'a> for LazyInstance { fn discard_first(fa: Self::F, fb: Self::F) -> Self::F { drop(fa); fb } fn discard_second(fa: Self::F, fb: Self::F) -> Self::F { drop(fb); fa } } impl<'a> Monad<'a> for LazyInstance { fn bind( fa: Self::F, f: impl 'a + Send + FnOnce(A) -> Self::F, ) -> Self::F { Box::new(|| f(fa())()) } fn iterate(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F { loop { match f.next()() { ControlFlow::Continue(next_f) => f = next_f, ControlFlow::Break(b) => return Self::pure(b), } } } fn join(ffa: Self::F>) -> Self::F { Box::new(|| ffa()()) } }