impl sugar

This commit is contained in:
AF 2023-03-26 11:59:50 +00:00
parent f82020f766
commit 6aa149ee6a
9 changed files with 74 additions and 60 deletions

View File

@ -1,4 +1,4 @@
use std::{rc::Rc, error::Error}; use std::{error::Error, rc::Rc};
use crate::func::*; use crate::func::*;
@ -38,7 +38,8 @@ pub trait Factory<Ctx: Context>: Clone {
type Mtbl: Mentionable<Ctx, Fctr = Self>; type Mtbl: Mentionable<Ctx, Fctr = Self>;
type ParseError: Error; type ParseError: Error;
fn deserialize<F: Deserializer>(&self, deserializer: F) -> Result<Self::Mtbl, Self::ParseError>; fn deserialize<F: Deserializer>(&self, deserializer: F)
-> Result<Self::Mtbl, Self::ParseError>;
} }
pub trait Origin<'a, Ctx: Context>: 'a { pub trait Origin<'a, Ctx: Context>: 'a {

View File

@ -23,7 +23,7 @@ pub trait WeakFunctor {
/// } /// }
/// ///
/// impl Functor for VecClass { /// impl Functor for VecClass {
/// fn fmap<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>(f: F, fa: Self::F<'a, A>) -> Self::F<'a, B> { /// fn fmap<'a, A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B>
/// fa.into_iter().map(f).collect() /// fa.into_iter().map(f).collect()
/// } /// }
/// } /// }
@ -41,8 +41,8 @@ pub trait WeakFunctor {
/// } /// }
/// ///
/// impl CloneFunctor for VecClass { /// impl CloneFunctor for VecClass {
/// fn clone_fmap<'a, A: 'a + Clone, B: 'a + Clone, F: 'a + Fn(A) -> B>( /// fn clone_fmap<'a, A: 'a + Clone, B: 'a + Clone>(
/// f: F, /// f: impl 'a + Fn(A) -> B,
/// fa: Self::ClF<'a, A>, /// fa: Self::ClF<'a, A>,
/// ) -> Self::ClF<'a, B> { /// ) -> Self::ClF<'a, B> {
/// fa.into_iter().map(f).collect() /// fa.into_iter().map(f).collect()
@ -51,7 +51,7 @@ pub trait WeakFunctor {
/// ``` /// ```
pub trait Functor: WeakFunctor { pub trait Functor: WeakFunctor {
fn fmap<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>(f: F, fa: Self::F<'a, A>) -> Self::F<'a, B> fn fmap<'a, A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B>
where where
Self: 'a; Self: 'a;
@ -71,14 +71,14 @@ pub trait Functor: WeakFunctor {
} }
pub trait ApplicativeSeq: Functor { pub trait ApplicativeSeq: Functor {
fn seq<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>( fn seq<'a, A: 'a, B: 'a>(
ff: Self::F<'a, F>, ff: Self::F<'a, impl 'a + FnOnce(A) -> B>,
fa: Self::F<'a, A>, fa: Self::F<'a, A>,
) -> Self::F<'a, B> ) -> Self::F<'a, B>
where where
Self: 'a; Self: 'a;
fn _la2<'a, A: 'a, B: 'a, C: 'a, F: 'a + FnOnce(A, B) -> C>( fn _la2<'a, A: 'a, B: 'a, C: 'a>(
f: F, f: impl 'a + FnOnce(A, B) -> C,
fa: Self::F<'a, A>, fa: Self::F<'a, A>,
fb: Self::F<'a, B>, fb: Self::F<'a, B>,
) -> Self::F<'a, C> ) -> Self::F<'a, C>
@ -90,15 +90,15 @@ pub trait ApplicativeSeq: Functor {
} }
pub trait ApplicativeLA2: Functor { pub trait ApplicativeLA2: Functor {
fn la2<'a, A: 'a, B: 'a, C: 'a, F: 'a + FnOnce(A, B) -> C>( fn la2<'a, A: 'a, B: 'a, C: 'a>(
f: F, f: impl 'a + FnOnce(A, B) -> C,
fa: Self::F<'a, A>, fa: Self::F<'a, A>,
fb: Self::F<'a, B>, fb: Self::F<'a, B>,
) -> Self::F<'a, C> ) -> Self::F<'a, C>
where where
Self: 'a; Self: 'a;
fn _seq<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>( fn _seq<'a, A: 'a, B: 'a>(
ff: Self::F<'a, F>, ff: Self::F<'a, impl 'a + FnOnce(A) -> B>,
fa: Self::F<'a, A>, fa: Self::F<'a, A>,
) -> Self::F<'a, B> ) -> Self::F<'a, B>
where where
@ -127,9 +127,9 @@ pub trait Applicative: Functor + ApplicativeSeq + ApplicativeLA2 {
} }
pub trait Monad: Applicative { pub trait Monad: Applicative {
fn bind<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> Self::F<'a, B>>( fn bind<'a, A: 'a, B: 'a>(
fa: Self::F<'a, A>, fa: Self::F<'a, A>,
f: F, f: impl 'a + FnOnce(A) -> Self::F<'a, B>,
) -> Self::F<'a, B> ) -> Self::F<'a, B>
where where
Self: 'a; Self: 'a;

View File

@ -7,7 +7,7 @@ impl<U: WeakFunctor, V: WeakFunctor> WeakFunctor for CompositionClass<U, V> {
} }
impl<U: Functor, V: Functor> Functor for CompositionClass<U, V> { impl<U: Functor, V: Functor> Functor for CompositionClass<U, V> {
fn fmap<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>(f: F, fa: Self::F<'a, A>) -> Self::F<'a, B> fn fmap<'a, A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B>
where where
Self: 'a, Self: 'a,
{ {
@ -30,8 +30,8 @@ impl<U: Functor, V: Functor> Functor for CompositionClass<U, V> {
} }
impl<U: ApplicativeLA2, V: ApplicativeSeq> ApplicativeSeq for CompositionClass<U, V> { impl<U: ApplicativeLA2, V: ApplicativeSeq> ApplicativeSeq for CompositionClass<U, V> {
fn seq<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>( fn seq<'a, A: 'a, B: 'a>(
ff: Self::F<'a, F>, ff: Self::F<'a, impl 'a + FnOnce(A) -> B>,
fa: Self::F<'a, A>, fa: Self::F<'a, A>,
) -> Self::F<'a, B> ) -> Self::F<'a, B>
where where
@ -42,8 +42,8 @@ impl<U: ApplicativeLA2, V: ApplicativeSeq> ApplicativeSeq for CompositionClass<U
} }
impl<U: ApplicativeLA2, V: ApplicativeLA2> ApplicativeLA2 for CompositionClass<U, V> { impl<U: ApplicativeLA2, V: ApplicativeLA2> ApplicativeLA2 for CompositionClass<U, V> {
fn la2<'a, A: 'a, B: 'a, C: 'a, F: 'a + FnOnce(A, B) -> C>( fn la2<'a, A: 'a, B: 'a, C: 'a>(
f: F, f: impl 'a + FnOnce(A, B) -> C,
fa: Self::F<'a, A>, fa: Self::F<'a, A>,
fb: Self::F<'a, B>, fb: Self::F<'a, B>,
) -> Self::F<'a, C> ) -> Self::F<'a, C>
@ -53,3 +53,17 @@ impl<U: ApplicativeLA2, V: ApplicativeLA2> ApplicativeLA2 for CompositionClass<U
U::la2(|ua, ub| V::la2(f, ua, ub), fa, fb) U::la2(|ua, ub| V::la2(f, ua, ub), fa, fb)
} }
} }
pub fn compose<'a>(f: impl 'a + Fn(i16) -> i32, g: impl 'a + Fn(i8) -> i16) -> impl 'a + Fn(i8) -> i32 {
move |x| f(g(x))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_compose() {
assert_eq!(compose(|x| (x + 5).into(), |x| (x + 3).into())(2), 10);
}
}

View File

@ -11,7 +11,7 @@ impl WeakFunctor for FutureClass {
} }
impl Functor for FutureClass { impl Functor for FutureClass {
fn fmap<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>(f: F, fa: Self::F<'a, A>) -> Self::F<'a, B> { fn fmap<'a, A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B> {
Box::pin(async { f(fa.await) }) Box::pin(async { f(fa.await) })
} }
@ -24,8 +24,8 @@ impl Functor for FutureClass {
} }
impl ApplicativeSeq for FutureClass { impl ApplicativeSeq for FutureClass {
fn seq<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>( fn seq<'a, A: 'a, B: 'a>(
ff: Self::F<'a, F>, ff: Self::F<'a, impl 'a + FnOnce(A) -> B>,
fa: Self::F<'a, A>, fa: Self::F<'a, A>,
) -> Self::F<'a, B> { ) -> Self::F<'a, B> {
Box::pin(async { Box::pin(async {
@ -36,8 +36,8 @@ impl ApplicativeSeq for FutureClass {
} }
impl ApplicativeLA2 for FutureClass { impl ApplicativeLA2 for FutureClass {
fn la2<'a, A: 'a, B: 'a, C: 'a, F: 'a + FnOnce(A, B) -> C>( fn la2<'a, A: 'a, B: 'a, C: 'a>(
f: F, f: impl 'a + FnOnce(A, B) -> C,
fa: Self::F<'a, A>, fa: Self::F<'a, A>,
fb: Self::F<'a, B>, fb: Self::F<'a, B>,
) -> Self::F<'a, C> { ) -> Self::F<'a, C> {
@ -63,9 +63,9 @@ impl Applicative for FutureClass {
} }
impl Monad for FutureClass { impl Monad for FutureClass {
fn bind<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> Self::F<'a, B>>( fn bind<'a, A: 'a, B: 'a>(
fa: Self::F<'a, A>, fa: Self::F<'a, A>,
f: F, f: impl 'a + FnOnce(A) -> Self::F<'a, B>,
) -> Self::F<'a, B> { ) -> Self::F<'a, B> {
Box::pin(async { f(fa.await).await }) Box::pin(async { f(fa.await).await })
} }

View File

@ -7,7 +7,7 @@ impl WeakFunctor for LazyClass {
} }
impl Functor for LazyClass { impl Functor for LazyClass {
fn fmap<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>(f: F, fa: Self::F<'a, A>) -> Self::F<'a, B> { fn fmap<'a, A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B> {
Box::new(|| f(fa())) Box::new(|| f(fa()))
} }
@ -23,8 +23,8 @@ impl Functor for LazyClass {
} }
impl ApplicativeSeq for LazyClass { impl ApplicativeSeq for LazyClass {
fn seq<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>( fn seq<'a, A: 'a, B: 'a>(
ff: Self::F<'a, F>, ff: Self::F<'a, impl 'a + FnOnce(A) -> B>,
fa: Self::F<'a, A>, fa: Self::F<'a, A>,
) -> Self::F<'a, B> { ) -> Self::F<'a, B> {
Box::new(|| ff()(fa())) Box::new(|| ff()(fa()))
@ -32,8 +32,8 @@ impl ApplicativeSeq for LazyClass {
} }
impl ApplicativeLA2 for LazyClass { impl ApplicativeLA2 for LazyClass {
fn la2<'a, A: 'a, B: 'a, C: 'a, F: 'a + FnOnce(A, B) -> C>( fn la2<'a, A: 'a, B: 'a, C: 'a>(
f: F, f: impl 'a + FnOnce(A, B) -> C,
fa: Self::F<'a, A>, fa: Self::F<'a, A>,
fb: Self::F<'a, B>, fb: Self::F<'a, B>,
) -> Self::F<'a, C> { ) -> Self::F<'a, C> {
@ -58,9 +58,9 @@ impl Applicative for LazyClass {
} }
impl Monad for LazyClass { impl Monad for LazyClass {
fn bind<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> Self::F<'a, B>>( fn bind<'a, A: 'a, B: 'a>(
fa: Self::F<'a, A>, fa: Self::F<'a, A>,
f: F, f: impl 'a + FnOnce(A) -> Self::F<'a, B>,
) -> Self::F<'a, B> { ) -> Self::F<'a, B> {
Box::new(|| f(fa())()) Box::new(|| f(fa())())
} }

View File

@ -7,7 +7,7 @@ impl WeakFunctor for OptionClass {
} }
impl Functor for OptionClass { impl Functor for OptionClass {
fn fmap<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>(f: F, fa: Self::F<'a, A>) -> Self::F<'a, B> { fn fmap<'a, A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B> {
fa.map(f) fa.map(f)
} }
@ -17,8 +17,8 @@ impl Functor for OptionClass {
} }
impl ApplicativeSeq for OptionClass { impl ApplicativeSeq for OptionClass {
fn seq<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>( fn seq<'a, A: 'a, B: 'a>(
ff: Self::F<'a, F>, ff: Self::F<'a, impl 'a + FnOnce(A) -> B>,
fa: Self::F<'a, A>, fa: Self::F<'a, A>,
) -> Self::F<'a, B> { ) -> Self::F<'a, B> {
Self::pure(ff?(fa?)) Self::pure(ff?(fa?))
@ -26,8 +26,8 @@ impl ApplicativeSeq for OptionClass {
} }
impl ApplicativeLA2 for OptionClass { impl ApplicativeLA2 for OptionClass {
fn la2<'a, A: 'a, B: 'a, C: 'a, F: 'a + FnOnce(A, B) -> C>( fn la2<'a, A: 'a, B: 'a, C: 'a>(
f: F, f: impl 'a + FnOnce(A, B) -> C,
fa: Self::F<'a, A>, fa: Self::F<'a, A>,
fb: Self::F<'a, B>, fb: Self::F<'a, B>,
) -> Self::F<'a, C> { ) -> Self::F<'a, C> {
@ -52,9 +52,9 @@ impl Applicative for OptionClass {
} }
impl Monad for OptionClass { impl Monad for OptionClass {
fn bind<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> Self::F<'a, B>>( fn bind<'a, A: 'a, B: 'a>(
fa: Self::F<'a, A>, fa: Self::F<'a, A>,
f: F, f: impl 'a + FnOnce(A) -> Self::F<'a, B>,
) -> Self::F<'a, B> { ) -> Self::F<'a, B> {
f(fa?) f(fa?)
} }

View File

@ -7,7 +7,7 @@ impl<E> WeakFunctor for ResultClass<E> {
} }
impl<E> Functor for ResultClass<E> { impl<E> Functor for ResultClass<E> {
fn fmap<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>(f: F, fa: Self::F<'a, A>) -> Self::F<'a, B> { fn fmap<'a, A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B> {
fa.map(f) fa.map(f)
} }
@ -17,8 +17,8 @@ impl<E> Functor for ResultClass<E> {
} }
impl<E> ApplicativeSeq for ResultClass<E> { impl<E> ApplicativeSeq for ResultClass<E> {
fn seq<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>( fn seq<'a, A: 'a, B: 'a>(
ff: Self::F<'a, F>, ff: Self::F<'a, impl 'a + FnOnce(A) -> B>,
fa: Self::F<'a, A>, fa: Self::F<'a, A>,
) -> Self::F<'a, B> { ) -> Self::F<'a, B> {
Self::pure(ff?(fa?)) Self::pure(ff?(fa?))
@ -26,8 +26,8 @@ impl<E> ApplicativeSeq for ResultClass<E> {
} }
impl<E> ApplicativeLA2 for ResultClass<E> { impl<E> ApplicativeLA2 for ResultClass<E> {
fn la2<'a, A: 'a, B: 'a, C: 'a, F: 'a + FnOnce(A, B) -> C>( fn la2<'a, A: 'a, B: 'a, C: 'a>(
f: F, f: impl 'a + FnOnce(A, B) -> C,
fa: Self::F<'a, A>, fa: Self::F<'a, A>,
fb: Self::F<'a, B>, fb: Self::F<'a, B>,
) -> Self::F<'a, C> { ) -> Self::F<'a, C> {
@ -52,9 +52,9 @@ impl<E> Applicative for ResultClass<E> {
} }
impl<E> Monad for ResultClass<E> { impl<E> Monad for ResultClass<E> {
fn bind<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> Self::F<'a, B>>( fn bind<'a, A: 'a, B: 'a>(
fa: Self::F<'a, A>, fa: Self::F<'a, A>,
f: F, f: impl 'a + FnOnce(A) -> Self::F<'a, B>,
) -> Self::F<'a, B> { ) -> Self::F<'a, B> {
f(fa?) f(fa?)
} }

View File

@ -7,7 +7,7 @@ impl WeakFunctor for SoloClass {
} }
impl Functor for SoloClass { impl Functor for SoloClass {
fn fmap<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>(f: F, fa: Self::F<'a, A>) -> Self::F<'a, B> { fn fmap<'a, A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B> {
f(fa) f(fa)
} }
@ -22,8 +22,8 @@ impl Functor for SoloClass {
} }
impl ApplicativeSeq for SoloClass { impl ApplicativeSeq for SoloClass {
fn seq<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>( fn seq<'a, A: 'a, B: 'a>(
ff: Self::F<'a, F>, ff: Self::F<'a, impl 'a + FnOnce(A) -> B>,
fa: Self::F<'a, A>, fa: Self::F<'a, A>,
) -> Self::F<'a, B> { ) -> Self::F<'a, B> {
ff(fa) ff(fa)
@ -31,8 +31,8 @@ impl ApplicativeSeq for SoloClass {
} }
impl ApplicativeLA2 for SoloClass { impl ApplicativeLA2 for SoloClass {
fn la2<'a, A: 'a, B: 'a, C: 'a, F: 'a + FnOnce(A, B) -> C>( fn la2<'a, A: 'a, B: 'a, C: 'a>(
f: F, f: impl 'a + FnOnce(A, B) -> C,
fa: Self::F<'a, A>, fa: Self::F<'a, A>,
fb: Self::F<'a, B>, fb: Self::F<'a, B>,
) -> Self::F<'a, C> { ) -> Self::F<'a, C> {
@ -57,15 +57,14 @@ impl Applicative for SoloClass {
} }
impl Monad for SoloClass { impl Monad for SoloClass {
fn bind<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> Self::F<'a, B>>( fn bind<'a, A: 'a, B: 'a>(
fa: Self::F<'a, A>, fa: Self::F<'a, A>,
f: F, f: impl 'a + FnOnce(A) -> Self::F<'a, B>,
) -> Self::F<'a, B> { ) -> Self::F<'a, B> {
f(fa) f(fa)
} }
fn join<'a, A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> fn join<'a, A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A> {
{
ffa ffa
} }
} }

View File

@ -3,8 +3,8 @@ pub trait CloneWeakFunctor {
} }
pub trait CloneFunctor: CloneWeakFunctor { pub trait CloneFunctor: CloneWeakFunctor {
fn clone_fmap<'a, A: 'a + Clone, B: 'a + Clone, F: 'a + Fn(A) -> B>( fn clone_fmap<'a, A: 'a + Clone, B: 'a + Clone>(
f: F, f: impl 'a + Fn(A) -> B,
fa: Self::ClF<'a, A>, fa: Self::ClF<'a, A>,
) -> Self::ClF<'a, B>; ) -> Self::ClF<'a, B>;