simplify TracedClass
This commit is contained in:
parent
cb650c81b5
commit
5863532338
@ -282,7 +282,7 @@ mod tests {
|
|||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
assert!(traced.a.is_ok());
|
assert!(traced.value.is_ok());
|
||||||
// panic!("{:?}", traced.render().to_vec());D
|
// panic!("{:?}", traced.render().to_vec());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
use crate::func::*;
|
use crate::func::*;
|
||||||
|
|
||||||
pub trait Effect {
|
pub trait Effect {
|
||||||
fn pure() -> Self;
|
fn e_pure() -> Self;
|
||||||
|
|
||||||
fn seq(lhs: Self, rhs: Self) -> Self;
|
fn e_seq(lhs: Self, rhs: Self) -> Self;
|
||||||
|
|
||||||
fn after(self, effect: Self) -> Self;
|
fn e_after(self, effect: Self) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -15,10 +15,10 @@ pub struct WithEffect<A, E> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<A, E: Effect> WithEffect<A, E> {
|
impl<A, E: Effect> WithEffect<A, E> {
|
||||||
fn after(self, effect: E) -> Self {
|
fn e_after(self, effect: E) -> Self {
|
||||||
WithEffect {
|
WithEffect {
|
||||||
value: self.value,
|
value: self.value,
|
||||||
effect: self.effect.after(effect),
|
effect: self.effect.e_after(effect),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,7 +62,7 @@ impl<E: Effect> Pure for EffectClass<E> {
|
|||||||
{
|
{
|
||||||
WithEffect {
|
WithEffect {
|
||||||
value: a,
|
value: a,
|
||||||
effect: E::pure(),
|
effect: E::e_pure(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,7 +77,7 @@ impl<E: Effect> ApplicativeSeq for EffectClass<E> {
|
|||||||
{
|
{
|
||||||
WithEffect {
|
WithEffect {
|
||||||
value: (ff.value)(fa.value),
|
value: (ff.value)(fa.value),
|
||||||
effect: E::seq(ff.effect, fa.effect),
|
effect: E::e_seq(ff.effect, fa.effect),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -93,7 +93,7 @@ impl<E: Effect> ApplicativeLA2 for EffectClass<E> {
|
|||||||
{
|
{
|
||||||
WithEffect {
|
WithEffect {
|
||||||
value: f(fa.value, fb.value),
|
value: f(fa.value, fb.value),
|
||||||
effect: E::seq(fa.effect, fb.effect),
|
effect: E::e_seq(fa.effect, fb.effect),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,7 +105,7 @@ impl<E: Effect> ApplicativeTuple for EffectClass<E> {
|
|||||||
{
|
{
|
||||||
WithEffect {
|
WithEffect {
|
||||||
value: (fa.value, fb.value),
|
value: (fa.value, fb.value),
|
||||||
effect: E::seq(fa.effect, fb.effect),
|
effect: E::e_seq(fa.effect, fb.effect),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -118,7 +118,7 @@ impl<E: Effect> Applicative for EffectClass<E> {
|
|||||||
drop(fa.value);
|
drop(fa.value);
|
||||||
WithEffect {
|
WithEffect {
|
||||||
value: fb.value,
|
value: fb.value,
|
||||||
effect: E::seq(fa.effect, fb.effect),
|
effect: E::e_seq(fa.effect, fb.effect),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,7 +129,7 @@ impl<E: Effect> Applicative for EffectClass<E> {
|
|||||||
drop(fb.value);
|
drop(fb.value);
|
||||||
WithEffect {
|
WithEffect {
|
||||||
value: fa.value,
|
value: fa.value,
|
||||||
effect: E::seq(fa.effect, fb.effect),
|
effect: E::e_seq(fa.effect, fb.effect),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -142,17 +142,17 @@ impl<E: Effect> Monad for EffectClass<E> {
|
|||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
{
|
{
|
||||||
f(fa.value).after(fa.effect)
|
f(fa.value).e_after(fa.effect)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iterate<'a, B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B>
|
fn iterate<'a, B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B>
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
{
|
{
|
||||||
let mut effect = E::pure();
|
let mut effect = E::e_pure();
|
||||||
loop {
|
loop {
|
||||||
let fa = f.next();
|
let fa = f.next();
|
||||||
effect = fa.effect.after(effect);
|
effect = fa.effect.e_after(effect);
|
||||||
match fa.value {
|
match fa.value {
|
||||||
ControlFlow::Continue(next_f) => f = next_f,
|
ControlFlow::Continue(next_f) => f = next_f,
|
||||||
ControlFlow::Break(b) => return WithEffect { value: b, effect },
|
ControlFlow::Break(b) => return WithEffect { value: b, effect },
|
||||||
@ -165,7 +165,7 @@ impl<E: Effect> Monad for EffectClass<E> {
|
|||||||
Self::F<'a, A>: 'a,
|
Self::F<'a, A>: 'a,
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
{
|
{
|
||||||
ffa.value.after(ffa.effect)
|
ffa.value.e_after(ffa.effect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,12 +272,12 @@ mod tests {
|
|||||||
let traced = stack.clone().vec();
|
let traced = stack.clone().vec();
|
||||||
assert_eq!(traced.length(), 0);
|
assert_eq!(traced.length(), 0);
|
||||||
assert_eq!(traced.width(), 0);
|
assert_eq!(traced.width(), 0);
|
||||||
assert_eq!(format!("{}", traced.t), ".");
|
assert_eq!(format!("{}", traced.effect), ".");
|
||||||
let stack: T<TestContextTraced> = Rc::new(stack).trace()?;
|
let stack: T<TestContextTraced> = Rc::new(stack).trace()?;
|
||||||
let traced = stack.clone().vec();
|
let traced = stack.clone().vec();
|
||||||
assert_eq!(traced.length(), 3);
|
assert_eq!(traced.length(), 3);
|
||||||
assert_eq!(traced.width(), 1);
|
assert_eq!(traced.width(), 1);
|
||||||
assert_eq!(format!("{}", traced.t), "( ? > ? > ? )");
|
assert_eq!(format!("{}", traced.effect), "( ? > ? > ? )");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,8 +22,21 @@ pub use self::traced::*;
|
|||||||
pub struct TracedDiagnostic;
|
pub struct TracedDiagnostic;
|
||||||
|
|
||||||
/// Implementation of [`Monad`] for [Traced] objects.
|
/// Implementation of [`Monad`] for [Traced] objects.
|
||||||
#[derive(CovariantFunctor)]
|
pub type TracedClass = classes::effect::EffectClass<TraceBox>;
|
||||||
pub struct TracedClass;
|
|
||||||
|
impl classes::effect::Effect for TraceBox {
|
||||||
|
fn e_pure() -> Self {
|
||||||
|
TraceBox::pure()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn e_seq(lhs: Self, rhs: Self) -> Self {
|
||||||
|
TraceBox::parallel(lhs, rhs)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn e_after(self, effect: Self) -> Self {
|
||||||
|
self.after(effect)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
trait WithTrace: Sized {
|
trait WithTrace: Sized {
|
||||||
fn with_trace(self, t: TraceBox) -> Traced<Self>;
|
fn with_trace(self, t: TraceBox) -> Traced<Self>;
|
||||||
@ -31,15 +44,18 @@ trait WithTrace: Sized {
|
|||||||
|
|
||||||
impl<A> WithTrace for A {
|
impl<A> WithTrace for A {
|
||||||
fn with_trace(self, t: TraceBox) -> Traced<Self> {
|
fn with_trace(self, t: TraceBox) -> Traced<Self> {
|
||||||
Traced { a: self, t }
|
Traced {
|
||||||
|
value: self,
|
||||||
|
effect: t,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A> Traced<A> {
|
impl<A> Traced<A> {
|
||||||
fn wrapped(self, event: &str) -> Self {
|
fn wrapped(self, event: &str) -> Self {
|
||||||
Traced {
|
Traced {
|
||||||
a: self.a,
|
value: self.value,
|
||||||
t: self.t.wrapped(event),
|
effect: self.effect.wrapped(event),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,178 +65,24 @@ impl<A> Traced<A> {
|
|||||||
|
|
||||||
fn after(self, t: TraceBox) -> Self {
|
fn after(self, t: TraceBox) -> Self {
|
||||||
Traced {
|
Traced {
|
||||||
a: self.a,
|
value: self.value,
|
||||||
t: self.t.after(t),
|
effect: self.effect.after(t),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn before(self, t: TraceBox) -> Self {
|
fn before(self, t: TraceBox) -> Self {
|
||||||
Traced {
|
Traced {
|
||||||
a: self.a,
|
value: self.value,
|
||||||
t: self.t.before(t),
|
effect: self.effect.before(t),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn length(&self) -> usize {
|
pub fn length(&self) -> usize {
|
||||||
self.t.length()
|
self.effect.length()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn width(&self) -> usize {
|
pub fn width(&self) -> usize {
|
||||||
self.t.width()
|
self.effect.width()
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WeakFunctor for TracedClass {
|
|
||||||
type F<'a, A: 'a> = Traced<A>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Functor for TracedClass {
|
|
||||||
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_trace(fa.t)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn replace<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B>
|
|
||||||
where
|
|
||||||
Self: 'a,
|
|
||||||
{
|
|
||||||
b.with_trace(fa.t)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn void<'a, A: 'a>(fa: Self::F<'a, A>) -> Self::F<'a, ()>
|
|
||||||
where
|
|
||||||
Self: 'a,
|
|
||||||
{
|
|
||||||
().with_trace(fa.t)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Pure for TracedClass {
|
|
||||||
fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> {
|
|
||||||
a.with_trace(TraceBox::pure())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ApplicativeSeq for TracedClass {
|
|
||||||
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_trace(TraceBox::parallel(ff.t, fa.t))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ApplicativeLA2 for TracedClass {
|
|
||||||
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_trace(TraceBox::parallel(fa.t, fb.t))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ApplicativeTuple for TracedClass {
|
|
||||||
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_trace(TraceBox::parallel(fa.t, fb.t))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Applicative for TracedClass {
|
|
||||||
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_trace(TraceBox::parallel(fa.t, fb.t))
|
|
||||||
}
|
|
||||||
|
|
||||||
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_trace(TraceBox::parallel(fa.t, fb.t))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Monad for TracedClass {
|
|
||||||
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).after(fa.t)
|
|
||||||
}
|
|
||||||
|
|
||||||
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 t = TraceBox::pure();
|
|
||||||
loop {
|
|
||||||
let fa = f(a);
|
|
||||||
t = fa.t.after(t);
|
|
||||||
match fa.a {
|
|
||||||
ControlFlow::Continue(next_a) => a = next_a,
|
|
||||||
ControlFlow::Break(b) => return b.with_trace(t),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 t = TraceBox::pure();
|
|
||||||
loop {
|
|
||||||
let fa = f.next(a);
|
|
||||||
t = fa.t.after(t);
|
|
||||||
match fa.a {
|
|
||||||
ControlFlow::Continue((next_a, next_f)) => (a, f) = (next_a, next_f),
|
|
||||||
ControlFlow::Break(b) => return b.with_trace(t),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn iterate<'a, B: 'a>(mut f: impl Iterative<'a, T = Self, B = B>) -> Self::F<'a, B>
|
|
||||||
where
|
|
||||||
Self: 'a,
|
|
||||||
{
|
|
||||||
let mut t = TraceBox::pure();
|
|
||||||
loop {
|
|
||||||
let fa = f.next();
|
|
||||||
t = fa.t.after(t);
|
|
||||||
match fa.a {
|
|
||||||
ControlFlow::Continue(next_f) => f = next_f,
|
|
||||||
ControlFlow::Break(b) => return b.with_trace(t),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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.after(ffa.t)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ impl Trace {
|
|||||||
|
|
||||||
impl<A> Traced<A> {
|
impl<A> Traced<A> {
|
||||||
pub fn render(&self) -> WithLengthAndWidth<RenderedAny> {
|
pub fn render(&self) -> WithLengthAndWidth<RenderedAny> {
|
||||||
self.t.trace.render()
|
self.effect.trace.render()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,4 @@ use super::*;
|
|||||||
/// Wrapper containing the value and the corresponding execution trace.
|
/// Wrapper containing the value and the corresponding execution trace.
|
||||||
///
|
///
|
||||||
/// For what the trace contains, see its rendered form, [`RenderedAny`].
|
/// For what the trace contains, see its rendered form, [`RenderedAny`].
|
||||||
pub struct Traced<A> {
|
pub type Traced<A> = classes::effect::WithEffect<A, TraceBox>;
|
||||||
pub a: A,
|
|
||||||
pub t: TraceBox,
|
|
||||||
}
|
|
||||||
|
@ -25,15 +25,15 @@ impl Context for TestContextCounted {
|
|||||||
pub type CountedClass = classes::effect::EffectClass<usize>;
|
pub type CountedClass = classes::effect::EffectClass<usize>;
|
||||||
|
|
||||||
impl classes::effect::Effect for usize {
|
impl classes::effect::Effect for usize {
|
||||||
fn pure() -> Self {
|
fn e_pure() -> Self {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn seq(lhs: Self, rhs: Self) -> Self {
|
fn e_seq(lhs: Self, rhs: Self) -> Self {
|
||||||
max(lhs, rhs)
|
max(lhs, rhs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn after(self, effect: Self) -> Self {
|
fn e_after(self, effect: Self) -> Self {
|
||||||
self + effect
|
self + effect
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user