fp_library/types/
rc_fn.rs1use crate::{
5 classes::{Category, ClonableFn, Monoid, Semigroup, Semigroupoid, clonable_fn::ApplyFn},
6 functions::{compose, identity},
7 hkt::{Apply1L2T, Kind1L2T},
8};
9use std::rc::Rc;
10
11#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
19pub struct RcFnBrand;
20
21impl Kind1L2T for RcFnBrand {
22 type Output<'a, A, B> = Rc<dyn 'a + Fn(A) -> B>;
23}
24
25impl ClonableFn for RcFnBrand {
26 type Output<'a, A: 'a, B: 'a> = Apply1L2T<'a, Self, A, B>;
27
28 fn new<'a, A: 'a, B: 'a>(f: impl 'a + Fn(A) -> B) -> ApplyFn<'a, Self, A, B> {
29 Rc::new(f)
30 }
31}
32
33impl Semigroupoid for RcFnBrand {
34 fn compose<'a, ClonableFnBrand: 'a + ClonableFn, B, C, D>(
35 f: Apply1L2T<'a, Self, C, D>
36 ) -> ApplyFn<'a, ClonableFnBrand, Apply1L2T<'a, Self, B, C>, Apply1L2T<'a, Self, B, D>> {
37 ClonableFnBrand::new::<'a, _, _>(move |g: Apply1L2T<'a, Self, B, C>| {
38 Self::new::<'a, _, _>({
39 let f = f.clone();
40 move |a| compose::<'a, Self, _, _, _>(f.clone())(g.clone())(a)
41 })
42 })
43 }
44}
45
46impl Category for RcFnBrand {
47 fn identity<'a, A: 'a>() -> Apply1L2T<'a, Self, A, A> {
48 Self::new::<'a, _, _>(identity)
49 }
50}
51
52impl<'b, A: 'b + Clone, B: Semigroup<'b> + 'b> Semigroup<'b> for Rc<dyn 'b + Fn(A) -> B> {
53 fn append<'a, ClonableFnBrand: 'a + 'b + ClonableFn>(
54 a: Self
55 ) -> ApplyFn<'a, ClonableFnBrand, Self, Self>
56 where
57 Self: Sized,
58 'b: 'a,
59 {
60 ClonableFnBrand::new(move |b: Self| {
61 RcFnBrand::new({
62 let a = a.clone();
63 move |c: A| B::append::<ClonableFnBrand>(a(c.clone()))(b(c))
64 })
65 })
66 }
67}
68
69impl<'b, A: 'b + Clone, B: Monoid<'b> + 'b> Monoid<'b> for Rc<dyn 'b + Fn(A) -> B> {
70 fn empty() -> Self {
71 RcFnBrand::new(move |_| B::empty())
72 }
73}