simplify CountedClass

This commit is contained in:
AF 2023-05-14 06:03:46 +00:00
parent caca9add1b
commit cb650c81b5
2 changed files with 17 additions and 171 deletions

View File

@ -10,8 +10,8 @@ pub trait Effect {
#[derive(Clone)]
pub struct WithEffect<A, E> {
value: A,
effect: E,
pub value: A,
pub effect: E,
}
impl<A, E: Effect> WithEffect<A, E> {

View File

@ -22,188 +22,34 @@ impl Context for TestContextCounted {
}
}
#[derive(CovariantFunctor)]
pub struct CountedClass;
pub type CountedClass = classes::effect::EffectClass<usize>;
pub struct Counted<A> {
a: A,
n: usize,
impl classes::effect::Effect for usize {
fn pure() -> Self {
0
}
trait WithCount: Sized {
fn with_count(self, n: usize) -> Counted<Self>;
fn seq(lhs: Self, rhs: Self) -> Self {
max(lhs, rhs)
}
impl<A> WithCount for A {
fn with_count(self, n: usize) -> Counted<Self> {
Counted { a: self, n }
fn after(self, effect: Self) -> Self {
self + effect
}
}
pub type Counted<A> = classes::effect::WithEffect<A, usize>;
impl<A> Counted<A> {
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<A>;
}
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<B, A>>,
) -> 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
}
}