impl
s in tests
This commit is contained in:
parent
5d9a0a10df
commit
504c0abc4c
@ -9,10 +9,10 @@ pub trait FunctorTestSuite: WeakFunctor + Eqr {
|
||||
pub fn functor_follows_laws<T: Functor + FunctorTestSuite>() -> R {
|
||||
let mut res = R::default();
|
||||
T::sample(|pa| {
|
||||
res += fmap_respects_identity::<T, _, _>(|| pa(2));
|
||||
res += fmap_respects_identity::<T, _>(|| pa(2));
|
||||
});
|
||||
T::sample(|pa| {
|
||||
res += fmap_respects_composition::<T, _, _, _, _, _, _>(|x| x + 5, |x| x + 3, || pa(2));
|
||||
res += fmap_respects_composition::<T, _, _, _>(|x| x + 5, |x| x + 3, || pa(2));
|
||||
});
|
||||
res
|
||||
}
|
||||
@ -20,12 +20,12 @@ pub fn functor_follows_laws<T: Functor + FunctorTestSuite>() -> R {
|
||||
pub fn applicative_follows_laws<T: Applicative + FunctorTestSuite>() -> R {
|
||||
let mut res = functor_follows_laws::<T>();
|
||||
T::sample(|pa| {
|
||||
res += seq_respects_identity::<T, _, _>(|| pa(2));
|
||||
res += seq_respects_identity::<T, _>(|| pa(2));
|
||||
});
|
||||
T::sample(|pa| {
|
||||
T::sample(|pg| {
|
||||
T::sample(|pf| {
|
||||
res += seq_respects_composition::<T, _, _, _, _, _, _, _, _>(
|
||||
res += seq_respects_composition::<T, _, _, _, _, _>(
|
||||
|| pf(|x| x + 5),
|
||||
|| pg(|x| x + 3),
|
||||
|| pa(2),
|
||||
@ -33,21 +33,21 @@ pub fn applicative_follows_laws<T: Applicative + FunctorTestSuite>() -> R {
|
||||
})
|
||||
})
|
||||
});
|
||||
res += seq_is_homomorphic::<T, _, _, _, _>(|x| x + 3, || 2);
|
||||
res += seq_is_homomorphic::<T, _, _>(|x| x + 3, || 2);
|
||||
T::sample(|pf| {
|
||||
res += seq_respects_interchange::<T, _, _, _, _, _>(|| pf(|x| x + 3), || 2);
|
||||
res += seq_respects_interchange::<T, _, _, _>(|| pf(|x| x + 3), || 2);
|
||||
});
|
||||
T::sample(|pa| {
|
||||
T::sample(|pf| {
|
||||
res += seq_can_be_expressed_via_la2::<T, _, _, _, _, _>(|| pf(|x| x + 3), || pa(2));
|
||||
res += seq_can_be_expressed_via_la2::<T, _, _, _>(|| pf(|x| x + 3), || pa(2));
|
||||
})
|
||||
});
|
||||
T::sample(|pa| {
|
||||
res += fmap_can_be_expressed_via_seq::<T, _, _, _, _>(|x| x + 3, || pa(2));
|
||||
res += fmap_can_be_expressed_via_seq::<T, _, _>(|x| x + 3, || pa(2));
|
||||
});
|
||||
T::sample(|pa| {
|
||||
T::sample(|pb| {
|
||||
res += discard_can_be_expressed_via_seq_or_la2::<T, _, _, _, _>(|| pa(2), || pb(2));
|
||||
res += discard_can_be_expressed_via_seq_or_la2::<T, _, _>(|| pa(2), || pb(2));
|
||||
})
|
||||
});
|
||||
res
|
||||
@ -57,29 +57,25 @@ pub fn monad_follows_laws<T: Monad + FunctorTestSuite>() -> R
|
||||
where {
|
||||
let mut res = applicative_follows_laws::<T>();
|
||||
T::sample(|pa| {
|
||||
res += bind_respects_left_identity::<T, _, _, _, _>(|x| pa(x + 3), || 2);
|
||||
res += bind_respects_left_identity::<T, _, _>(|x| pa(x + 3), || 2);
|
||||
});
|
||||
T::sample(|pa| {
|
||||
res += bind_respects_right_identity::<T, _, _>(|| pa(2));
|
||||
res += bind_respects_right_identity::<T, _>(|| pa(2));
|
||||
});
|
||||
T::sample(|pa| {
|
||||
T::sample(|pg| {
|
||||
T::sample(|pf| {
|
||||
res += bind_is_associative::<T, _, _, _, _, _, _>(
|
||||
|x| pf(x + 5),
|
||||
|x| pg(x + 3),
|
||||
|| pa(2),
|
||||
);
|
||||
res += bind_is_associative::<T, _, _, _>(|x| pf(x + 5), |x| pg(x + 3), || pa(2));
|
||||
})
|
||||
})
|
||||
});
|
||||
T::sample(|pa| {
|
||||
T::sample(|pf| {
|
||||
seq_can_be_expressed_via_bind::<T, _, _, _, _, _>(|| pf(|x| x + 3), || pa(2));
|
||||
seq_can_be_expressed_via_bind::<T, _, _, _>(|| pf(|x| x + 3), || pa(2));
|
||||
})
|
||||
});
|
||||
T::sample(|pa| {
|
||||
res += fmap_can_be_expressed_via_bind::<T, _, _, _, _>(|x| x + 3, || pa(2));
|
||||
res += fmap_can_be_expressed_via_bind::<T, _, _>(|x| x + 3, || pa(2));
|
||||
});
|
||||
res
|
||||
}
|
||||
|
@ -88,13 +88,8 @@ impl AddAssign<R> for R {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fmap_respects_identity<
|
||||
'a,
|
||||
T: 'a + Functor + Eqr,
|
||||
A: 'a + Debug + PartialEq,
|
||||
FA0: Fn() -> T::F<'a, A>,
|
||||
>(
|
||||
fa0: FA0,
|
||||
pub fn fmap_respects_identity<'a, T: 'a + Functor + Eqr, A: 'a + Debug + PartialEq>(
|
||||
fa0: impl Fn() -> T::F<'a, A>,
|
||||
) -> R {
|
||||
T::eqr("identity: fmap id == id", T::fmap(|a| a, fa0()), fa0())
|
||||
}
|
||||
@ -105,13 +100,10 @@ pub fn fmap_respects_composition<
|
||||
A: 'a,
|
||||
B: 'a,
|
||||
C: 'a + Debug + PartialEq,
|
||||
F: 'a + Copy + Fn(B) -> C,
|
||||
G: 'a + Copy + Fn(A) -> B,
|
||||
FA0: Fn() -> T::F<'a, A>,
|
||||
>(
|
||||
f: F,
|
||||
g: G,
|
||||
fa0: FA0,
|
||||
f: impl 'a + Copy + Fn(B) -> C,
|
||||
g: impl 'a + Copy + Fn(A) -> B,
|
||||
fa0: impl Fn() -> T::F<'a, A>,
|
||||
) -> R {
|
||||
T::eqr(
|
||||
"composition: fmap (f . g) == fmap f . fmap g",
|
||||
@ -120,13 +112,8 @@ pub fn fmap_respects_composition<
|
||||
)
|
||||
}
|
||||
|
||||
pub fn seq_respects_identity<
|
||||
'a,
|
||||
T: 'a + Applicative + Eqr,
|
||||
A: 'a + Debug + PartialEq,
|
||||
FA0: Fn() -> T::F<'a, A>,
|
||||
>(
|
||||
fa0: FA0,
|
||||
pub fn seq_respects_identity<'a, T: 'a + Applicative + Eqr, A: 'a + Debug + PartialEq>(
|
||||
fa0: impl Fn() -> T::F<'a, A>,
|
||||
) -> R {
|
||||
T::eqr(
|
||||
"identity: pure id <*> v = v",
|
||||
@ -143,13 +130,10 @@ pub fn seq_respects_composition<
|
||||
C: 'a + Debug + PartialEq,
|
||||
F: 'a + Fn(B) -> C,
|
||||
G: 'a + Fn(A) -> B,
|
||||
FF0: Fn() -> T::F<'a, F>,
|
||||
FG0: Fn() -> T::F<'a, G>,
|
||||
FA0: Fn() -> T::F<'a, A>,
|
||||
>(
|
||||
ff0: FF0,
|
||||
fg0: FG0,
|
||||
fa0: FA0,
|
||||
ff0: impl Fn() -> T::F<'a, F>,
|
||||
fg0: impl Fn() -> T::F<'a, G>,
|
||||
fa0: impl Fn() -> T::F<'a, A>,
|
||||
) -> R {
|
||||
T::eqr(
|
||||
"composition: pure (.) <*> u <*> v <*> w = u <*> (v <*> w)",
|
||||
@ -164,16 +148,9 @@ pub fn seq_respects_composition<
|
||||
)
|
||||
}
|
||||
|
||||
pub fn seq_is_homomorphic<
|
||||
'a,
|
||||
T: 'a + Applicative + Eqr,
|
||||
A: 'a,
|
||||
B: 'a + Debug + PartialEq,
|
||||
A0: Fn() -> A,
|
||||
F: 'a + Fn(A) -> B,
|
||||
>(
|
||||
f: F,
|
||||
a0: A0,
|
||||
pub fn seq_is_homomorphic<'a, T: 'a + Applicative + Eqr, A: 'a, B: 'a + Debug + PartialEq>(
|
||||
f: impl 'a + Fn(A) -> B,
|
||||
a0: impl Fn() -> A,
|
||||
) -> R {
|
||||
T::eqr(
|
||||
"homomorphism: pure f <*> pure x = pure (f x)",
|
||||
@ -188,11 +165,9 @@ pub fn seq_respects_interchange<
|
||||
A: 'a,
|
||||
B: 'a + Debug + PartialEq,
|
||||
F: 'a + Fn(A) -> B,
|
||||
A0: 'a + Fn() -> A,
|
||||
FF0: Fn() -> T::F<'a, F>,
|
||||
>(
|
||||
ff0: FF0,
|
||||
a0: A0,
|
||||
ff0: impl Fn() -> T::F<'a, F>,
|
||||
a0: impl 'a + Fn() -> A,
|
||||
) -> R {
|
||||
T::eqr(
|
||||
"interchange: u <*> pure y = pure ($ y) <*> u",
|
||||
@ -207,11 +182,9 @@ pub fn seq_can_be_expressed_via_la2<
|
||||
A: 'a,
|
||||
B: 'a + Debug + PartialEq,
|
||||
F: 'a + Fn(A) -> B,
|
||||
FA0: Fn() -> T::F<'a, A>,
|
||||
FF0: Fn() -> T::F<'a, F>,
|
||||
>(
|
||||
ff0: FF0,
|
||||
fa0: FA0,
|
||||
ff0: impl Fn() -> T::F<'a, F>,
|
||||
fa0: impl Fn() -> T::F<'a, A>,
|
||||
) -> R {
|
||||
T::eqr(
|
||||
"seq via la2: (<*>) = liftA2 id",
|
||||
@ -225,11 +198,9 @@ pub fn fmap_can_be_expressed_via_seq<
|
||||
T: 'a + Applicative + Eqr,
|
||||
A: 'a,
|
||||
B: 'a + Debug + PartialEq,
|
||||
F: 'a + Copy + Fn(A) -> B,
|
||||
FA0: Fn() -> T::F<'a, A>,
|
||||
>(
|
||||
f: F,
|
||||
fa0: FA0,
|
||||
f: impl 'a + Copy + Fn(A) -> B,
|
||||
fa0: impl Fn() -> T::F<'a, A>,
|
||||
) -> R {
|
||||
T::eqr(
|
||||
"fmap via seq: fmap f x = pure f <*> x",
|
||||
@ -243,11 +214,9 @@ pub fn discard_can_be_expressed_via_seq_or_la2<
|
||||
T: 'a + Applicative + Eqr,
|
||||
A: 'a,
|
||||
B: 'a + Debug + PartialEq,
|
||||
FA0: 'a + Fn() -> T::F<'a, A>,
|
||||
FB0: 'a + Fn() -> T::F<'a, B>,
|
||||
>(
|
||||
fa0: FA0,
|
||||
fb0: FB0,
|
||||
fa0: impl 'a + Fn() -> T::F<'a, A>,
|
||||
fb0: impl 'a + Fn() -> T::F<'a, B>,
|
||||
) -> R {
|
||||
T::eqr(
|
||||
"discard via seq: u *> v = (id <$ u) <*> v",
|
||||
@ -260,16 +229,9 @@ pub fn discard_can_be_expressed_via_seq_or_la2<
|
||||
)
|
||||
}
|
||||
|
||||
pub fn bind_respects_left_identity<
|
||||
'a,
|
||||
T: 'a + Monad + Eqr,
|
||||
A: 'a,
|
||||
B: 'a + Debug + PartialEq,
|
||||
F: 'a + Fn(A) -> T::F<'a, B>,
|
||||
A0: Fn() -> A,
|
||||
>(
|
||||
f: F,
|
||||
a0: A0,
|
||||
pub fn bind_respects_left_identity<'a, T: 'a + Monad + Eqr, A: 'a, B: 'a + Debug + PartialEq>(
|
||||
f: impl 'a + Fn(A) -> T::F<'a, B>,
|
||||
a0: impl Fn() -> A,
|
||||
) -> R {
|
||||
T::eqr(
|
||||
"left identity: pure a >>= k = k a",
|
||||
@ -278,13 +240,8 @@ pub fn bind_respects_left_identity<
|
||||
)
|
||||
}
|
||||
|
||||
pub fn bind_respects_right_identity<
|
||||
'a,
|
||||
T: 'a + Monad + Eqr,
|
||||
A: 'a + Debug + PartialEq,
|
||||
FA0: Fn() -> T::F<'a, A>,
|
||||
>(
|
||||
fa0: FA0,
|
||||
pub fn bind_respects_right_identity<'a, T: 'a + Monad + Eqr, A: 'a + Debug + PartialEq>(
|
||||
fa0: impl Fn() -> T::F<'a, A>,
|
||||
) -> R {
|
||||
T::eqr(
|
||||
"right identity: m >>= bind = m",
|
||||
@ -293,19 +250,10 @@ pub fn bind_respects_right_identity<
|
||||
)
|
||||
}
|
||||
|
||||
pub fn bind_is_associative<
|
||||
'a,
|
||||
T: 'a + Monad + Eqr,
|
||||
A: 'a,
|
||||
B: 'a,
|
||||
C: 'a + Debug + PartialEq,
|
||||
F: 'a + Clone + Fn(B) -> T::F<'a, C>,
|
||||
G: 'a + Clone + Fn(A) -> T::F<'a, B>,
|
||||
FA0: 'a + Fn() -> T::F<'a, A>,
|
||||
>(
|
||||
f: F,
|
||||
g: G,
|
||||
fa0: FA0,
|
||||
pub fn bind_is_associative<'a, T: 'a + Monad + Eqr, A: 'a, B: 'a, C: 'a + Debug + PartialEq>(
|
||||
f: impl 'a + Clone + Fn(B) -> T::F<'a, C>,
|
||||
g: impl 'a + Clone + Fn(A) -> T::F<'a, B>,
|
||||
fa0: impl 'a + Fn() -> T::F<'a, A>,
|
||||
) -> R {
|
||||
T::eqr(
|
||||
r"associativity: m >>= (\x -> k x >>= h) = (m >>= k) >>= h",
|
||||
@ -320,11 +268,9 @@ pub fn seq_can_be_expressed_via_bind<
|
||||
A: 'a,
|
||||
B: 'a + Debug + PartialEq,
|
||||
F: 'a + Fn(A) -> B,
|
||||
FA0: 'a + Fn() -> T::F<'a, A>,
|
||||
FF0: Fn() -> T::F<'a, F>,
|
||||
>(
|
||||
ff0: FF0,
|
||||
fa0: FA0,
|
||||
ff0: impl Fn() -> T::F<'a, F>,
|
||||
fa0: impl 'a + Fn() -> T::F<'a, A>,
|
||||
) -> R {
|
||||
T::eqr(
|
||||
r"seq via bind: m1 <*> m2 = m1 >>= (\x1 -> m2 >>= (\x2 -> pure (x1 x2)))",
|
||||
@ -333,16 +279,9 @@ pub fn seq_can_be_expressed_via_bind<
|
||||
)
|
||||
}
|
||||
|
||||
pub fn fmap_can_be_expressed_via_bind<
|
||||
'a,
|
||||
T: 'a + Monad + Eqr,
|
||||
A: 'a,
|
||||
B: 'a + Debug + PartialEq,
|
||||
F: 'a + Copy + Fn(A) -> B,
|
||||
FA0: 'a + Fn() -> T::F<'a, A>,
|
||||
>(
|
||||
f: F,
|
||||
fa0: FA0,
|
||||
pub fn fmap_can_be_expressed_via_bind<'a, T: 'a + Monad + Eqr, A: 'a, B: 'a + Debug + PartialEq>(
|
||||
f: impl 'a + Copy + Fn(A) -> B,
|
||||
fa0: impl 'a + Fn() -> T::F<'a, A>,
|
||||
) -> R {
|
||||
T::eqr(
|
||||
"fmap via bind: fmap f xs = xs >>= return . f",
|
||||
|
Loading…
Reference in New Issue
Block a user