diff --git a/src/func/classes/effect.rs b/src/func/classes/effect.rs
index 760a431..e5f29f3 100644
--- a/src/func/classes/effect.rs
+++ b/src/func/classes/effect.rs
@@ -10,8 +10,8 @@ pub trait Effect {
#[derive(Clone)]
pub struct WithEffect {
- value: A,
- effect: E,
+ pub value: A,
+ pub effect: E,
}
impl WithEffect {
diff --git a/src/testing/counted.rs b/src/testing/counted.rs
index da98c44..f718c25 100644
--- a/src/testing/counted.rs
+++ b/src/testing/counted.rs
@@ -22,188 +22,34 @@ impl Context for TestContextCounted {
}
}
-#[derive(CovariantFunctor)]
-pub struct CountedClass;
+pub type CountedClass = classes::effect::EffectClass;
-pub struct Counted {
- a: A,
- n: usize,
-}
+impl classes::effect::Effect for usize {
+ fn pure() -> Self {
+ 0
+ }
-trait WithCount: Sized {
- fn with_count(self, n: usize) -> Counted;
-}
+ fn seq(lhs: Self, rhs: Self) -> Self {
+ max(lhs, rhs)
+ }
-impl WithCount for A {
- fn with_count(self, n: usize) -> Counted {
- Counted { a: self, n }
+ fn after(self, effect: Self) -> Self {
+ self + effect
}
}
+pub type Counted = classes::effect::WithEffect;
+
impl Counted {
fn add(self, n: usize) -> Self {
Counted {
- a: self.a,
- n: self.n + n,
+ value: self.value,
+ effect: self.effect + n,
}
}
pub fn count(&self) -> usize {
- self.n
- }
-}
-
-impl WeakFunctor for CountedClass {
- type F<'a, A: 'a> = Counted;
-}
-
-impl Functor for CountedClass {
- fn fmap<'a, A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B>
- where
- Self: 'a,
- {
- f(fa.a).with_count(fa.n)
- }
-
- fn replace<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B>
- where
- Self: 'a,
- {
- b.with_count(fa.n)
- }
-
- fn void<'a, A: 'a>(fa: Self::F<'a, A>) -> Self::F<'a, ()>
- where
- Self: 'a,
- {
- ().with_count(fa.n)
- }
-}
-
-impl Pure for CountedClass {
- fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> {
- a.with_count(0)
- }
-}
-
-impl ApplicativeSeq for CountedClass {
- fn seq<'a, A: 'a, B: 'a>(
- ff: Self::F<'a, impl 'a + FnOnce(A) -> B>,
- fa: Self::F<'a, A>,
- ) -> Self::F<'a, B>
- where
- Self: 'a,
- {
- (ff.a)(fa.a).with_count(max(ff.n, fa.n))
- }
-}
-
-impl ApplicativeLA2 for CountedClass {
- fn la2<'a, A: 'a, B: 'a, C: 'a>(
- f: impl 'a + FnOnce(A, B) -> C,
- fa: Self::F<'a, A>,
- fb: Self::F<'a, B>,
- ) -> Self::F<'a, C>
- where
- Self: 'a,
- {
- f(fa.a, fb.a).with_count(max(fa.n, fb.n))
- }
-}
-
-impl ApplicativeTuple for CountedClass {
- fn tuple<'a, A: 'a, B: 'a>((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)>
- where
- Self: 'a,
- {
- (fa.a, fb.a).with_count(max(fa.n, fb.n))
- }
-}
-
-impl Applicative for CountedClass {
- fn discard_first<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B>
- where
- Self: 'a,
- {
- fb.a.with_count(max(fa.n, fb.n))
- }
-
- fn discard_second<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, A>
- where
- Self: 'a,
- {
- fa.a.with_count(max(fa.n, fb.n))
- }
-}
-
-impl Monad for CountedClass {
- fn bind<'a, A: 'a, B: 'a>(
- fa: Self::F<'a, A>,
- f: impl 'a + FnOnce(A) -> Self::F<'a, B>,
- ) -> Self::F<'a, B>
- where
- Self: 'a,
- {
- f(fa.a).add(fa.n)
- }
-
- fn iterate_mut<'a, A: 'a, B: 'a>(
- mut a: A,
- mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow>,
- ) -> Self::F<'a, B>
- where
- Self: 'a,
- {
- let mut n = 0;
- loop {
- let fa = f(a);
- n += fa.n;
- match fa.a {
- ControlFlow::Continue(next_a) => a = next_a,
- ControlFlow::Break(b) => return b.with_count(n),
- }
- }
- }
-
- fn iterate_argument<'a, A: 'a, B: 'a>(
- mut a: A,
- mut f: impl AIterative<'a, T = Self, A = A, B = B>,
- ) -> Self::F<'a, B>
- where
- Self: 'a,
- {
- let mut n = 0;
- loop {
- let fa = f.next(a);
- n += fa.n;
- match fa.a {
- ControlFlow::Continue((next_a, next_f)) => (a, f) = (next_a, next_f),
- ControlFlow::Break(b) => return b.with_count(n),
- }
- }
- }
-
- fn iterate<'a, B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B>
- where
- Self: 'a,
- {
- let mut n = 0;
- loop {
- let fa = f.next();
- n += fa.n;
- match fa.a {
- ControlFlow::Continue(next_f) => f = next_f,
- ControlFlow::Break(b) => return b.with_count(n),
- }
- }
- }
-
- fn join<'a, A: 'a>(ffa: Self::F<'a, Self::F<'a, A>>) -> Self::F<'a, A>
- where
- Self::F<'a, A>: 'a,
- Self: 'a,
- {
- ffa.a.add(ffa.n)
+ self.effect
}
}