extract tracing
This commit is contained in:
		
							parent
							
								
									8b61c936ca
								
							
						
					
					
						commit
						794d071fa9
					
				| @ -7,6 +7,7 @@ pub mod inlining; | ||||
| mod local_origin; | ||||
| pub mod nullable; | ||||
| pub mod point; | ||||
| pub mod tracing; | ||||
| mod typeless; | ||||
| 
 | ||||
| use std::{error::Error, fmt::Display, rc::Rc}; | ||||
|  | ||||
| @ -274,10 +274,12 @@ mod tests { | ||||
|         let traced = stack.clone().vec(); | ||||
|         assert_eq!(traced.length(), 0); | ||||
|         assert_eq!(traced.width(), 0); | ||||
|         assert_eq!(format!("{}", traced.t), "."); | ||||
|         let stack: T<TestContextTraced> = Rc::new(stack).trace()?; | ||||
|         let traced = stack.clone().vec(); | ||||
|         assert_eq!(traced.length(), 3); | ||||
|         assert_eq!(traced.width(), 1); | ||||
|         assert_eq!(format!("{}", traced.t), "( ? -> ? -> ? )"); | ||||
|         Ok(()) | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										189
									
								
								src/std/tracing.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								src/std/tracing.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,189 @@ | ||||
| mod trace; | ||||
| mod traced; | ||||
| 
 | ||||
| use crate::core::*; | ||||
| use crate::func::*; | ||||
| use trace::*; | ||||
| pub use traced::Traced; | ||||
| 
 | ||||
| pub struct TracedDiagnostic; | ||||
| 
 | ||||
| pub struct TracedClass; | ||||
| 
 | ||||
| trait WithTrace: Sized { | ||||
|     fn with_trace(self, t: TraceBox) -> Traced<Self>; | ||||
| } | ||||
| 
 | ||||
| impl<A> WithTrace for A { | ||||
|     fn with_trace(self, t: TraceBox) -> Traced<Self> { | ||||
|         Traced { a: self, t } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<A> Traced<A> { | ||||
|     pub fn wrapped(self, event: &str) -> Self { | ||||
|         Traced { | ||||
|             a: self.a, | ||||
|             t: self.t.wrapped(event), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn after_resolution(self) -> Self { | ||||
|         self.after(TraceBox::resolution()) | ||||
|     } | ||||
| 
 | ||||
|     fn after(self, t: TraceBox) -> Self { | ||||
|         Traced { | ||||
|             a: self.a, | ||||
|             t: self.t.after(t), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn before(self, t: TraceBox) -> Self { | ||||
|         Traced { | ||||
|             a: self.a, | ||||
|             t: self.t.before(t), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn length(&self) -> usize { | ||||
|         self.t.length() | ||||
|     } | ||||
| 
 | ||||
|     pub fn width(&self) -> usize { | ||||
|         self.t.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 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 pure<'a, A: 'a>(a: A) -> Self::F<'a, A> { | ||||
|         a.with_trace(TraceBox::pure()) | ||||
|     } | ||||
| 
 | ||||
|     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 ibind<'a, A: 'a, B: 'a>( | ||||
|         mut a: A, | ||||
|         mut f: impl 'a + FnMut(A) -> Self::F<'a, IState<A, B>>, | ||||
|     ) -> 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 { | ||||
|                 IState::Pending(next_a) => a = next_a, | ||||
|                 IState::Done(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) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Diagnostic<TracedClass> for TracedDiagnostic { | ||||
|     fn after<A>(fa: Traced<A>, event: &str) -> Traced<A> { | ||||
|         fa.after(TraceBox::event(event)) | ||||
|     } | ||||
| 
 | ||||
|     fn before<A>(fa: Traced<A>, event: &str) -> Traced<A> { | ||||
|         fa.before(TraceBox::event(event)) | ||||
|     } | ||||
| 
 | ||||
|     fn wrapped<A>(fa: Traced<A>, event: &str) -> Traced<A> { | ||||
|         fa.wrapped(event) | ||||
|     } | ||||
| } | ||||
							
								
								
									
										178
									
								
								src/std/tracing/trace.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								src/std/tracing/trace.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,178 @@ | ||||
| use std::{cmp::max, fmt::Display}; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| enum Trace { | ||||
|     Pure, | ||||
|     InvolvesOneResolution, | ||||
|     Event(String), | ||||
|     Parallel(TraceBox, TraceBox), | ||||
|     Sequential { first: TraceBox, second: TraceBox }, | ||||
|     Wrapped { name: String, trace: TraceBox }, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct TraceBox { | ||||
|     trace: Box<Trace>, | ||||
| } | ||||
| 
 | ||||
| impl Trace { | ||||
|     fn fmt_parallel(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         match self { | ||||
|             Trace::Parallel(a, b) => { | ||||
|                 f.write_fmt(format_args!("{} | {}", ParallelBox(a), ParallelBox(b))) | ||||
|             } | ||||
|             trace @ _ => f.write_fmt(format_args!("{}", trace)), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn fmt_sequential(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         match self { | ||||
|             Trace::Sequential { first, second } => f.write_fmt(format_args!( | ||||
|                 "{} -> {}", | ||||
|                 SequentialBox(first), | ||||
|                 SequentialBox(second) | ||||
|             )), | ||||
|             trace @ _ => f.write_fmt(format_args!("{}", trace)), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| struct ParallelBox<'a>(&'a TraceBox); | ||||
| 
 | ||||
| struct SequentialBox<'a>(&'a TraceBox); | ||||
| 
 | ||||
| impl<'a> Display for ParallelBox<'a> { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         self.0.trace.fmt_parallel(f) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'a> Display for SequentialBox<'a> { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         self.0.trace.fmt_sequential(f) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Display for Trace { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         match self { | ||||
|             Trace::Pure => f.write_fmt(format_args!(".")), | ||||
|             Trace::InvolvesOneResolution => f.write_fmt(format_args!("?")), | ||||
|             Trace::Event(event) => f.write_fmt(format_args!("{}", event)), | ||||
|             Trace::Parallel(a, b) => { | ||||
|                 f.write_fmt(format_args!("( {} | {} )", ParallelBox(a), ParallelBox(b))) | ||||
|             } | ||||
|             Trace::Sequential { first, second } => f.write_fmt(format_args!( | ||||
|                 "( {} -> {} )", | ||||
|                 SequentialBox(first), | ||||
|                 SequentialBox(second) | ||||
|             )), | ||||
|             Trace::Wrapped { name, trace } => f.write_fmt(format_args!("{} @ {}", name, trace)), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Display for TraceBox { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         f.write_fmt(format_args!("{}", self.trace)) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<Trace> for TraceBox { | ||||
|     fn from(value: Trace) -> Self { | ||||
|         TraceBox { | ||||
|             trace: value.into(), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<TraceBox> for Trace { | ||||
|     fn from(value: TraceBox) -> Self { | ||||
|         *value.trace | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Trace { | ||||
|     fn sequential(ta: Self, tb: Self) -> Self { | ||||
|         match (ta, tb) { | ||||
|             (Trace::Pure, a) => a, | ||||
|             (a, Trace::Pure) => a, | ||||
|             (a, b) => Trace::Sequential { | ||||
|                 first: a.into(), | ||||
|                 second: b.into(), | ||||
|             }, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn length(&self) -> usize { | ||||
|         match self { | ||||
|             Self::Pure => 0, | ||||
|             Self::InvolvesOneResolution => 1, | ||||
|             Self::Event(_) => 0, | ||||
|             Self::Parallel(a, b) => max(a.length(), b.length()), | ||||
|             Self::Sequential { first, second } => first.length() + second.length(), | ||||
|             Self::Wrapped { trace, .. } => trace.length(), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn width(&self) -> usize { | ||||
|         match self { | ||||
|             Self::Pure => 0, | ||||
|             Self::InvolvesOneResolution => 1, | ||||
|             Self::Event(_) => 0, | ||||
|             Self::Parallel(a, b) => a.width() + b.width(), | ||||
|             Self::Sequential { first, second } => max(first.width(), second.width()), | ||||
|             Self::Wrapped { trace, .. } => trace.width(), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn parallel(ta: Self, tb: Self) -> Self { | ||||
|         match (ta, tb) { | ||||
|             (Trace::Pure, a) => a, | ||||
|             (a, Trace::Pure) => a, | ||||
|             (a, b) => Trace::Parallel(a.into(), b.into()), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl TraceBox { | ||||
|     pub fn pure() -> Self { | ||||
|         Trace::Pure.into() | ||||
|     } | ||||
| 
 | ||||
|     pub fn resolution() -> Self { | ||||
|         Trace::InvolvesOneResolution.into() | ||||
|     } | ||||
| 
 | ||||
|     pub fn event(event: &str) -> Self { | ||||
|         Trace::Event(event.into()).into() | ||||
|     } | ||||
| 
 | ||||
|     pub fn wrapped(self, event: &str) -> Self { | ||||
|         Trace::Wrapped { | ||||
|             name: event.into(), | ||||
|             trace: self, | ||||
|         } | ||||
|         .into() | ||||
|     } | ||||
| 
 | ||||
|     pub fn after(self, t: Self) -> Self { | ||||
|         Trace::sequential(t.into(), self.into()).into() | ||||
|     } | ||||
| 
 | ||||
|     pub fn before(self, t: Self) -> Self { | ||||
|         Trace::sequential(self.into(), t.into()).into() | ||||
|     } | ||||
| 
 | ||||
|     pub fn parallel(ta: Self, tb: Self) -> Self { | ||||
|         Trace::parallel(ta.into(), tb.into()).into() | ||||
|     } | ||||
| 
 | ||||
|     pub fn length(&self) -> usize { | ||||
|         self.trace.length() | ||||
|     } | ||||
| 
 | ||||
|     pub fn width(&self) -> usize { | ||||
|         self.trace.width() | ||||
|     } | ||||
| } | ||||
							
								
								
									
										6
									
								
								src/std/tracing/traced.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/std/tracing/traced.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| use super::trace::*; | ||||
| 
 | ||||
| pub struct Traced<A> { | ||||
|     pub a: A, | ||||
|     pub t: TraceBox, | ||||
| } | ||||
| @ -1,10 +1,7 @@ | ||||
| use std::cmp::max; | ||||
| 
 | ||||
| use super::*; | ||||
| use crate::core::*; | ||||
| use crate::func::*; | ||||
| 
 | ||||
| pub struct TracedDiagnostic; | ||||
| use crate::std::tracing::*; | ||||
| 
 | ||||
| pub struct TestContextTraced; | ||||
| 
 | ||||
| @ -20,263 +17,6 @@ impl Context for TestContextTraced { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct TracedClass; | ||||
| 
 | ||||
| pub enum Trace { | ||||
|     Pure, | ||||
|     InvolvesOneResolution, | ||||
|     Event(String), | ||||
|     Parallel(Box<Trace>, Box<Trace>), | ||||
|     Sequential { | ||||
|         first: Box<Trace>, | ||||
|         second: Box<Trace>, | ||||
|     }, | ||||
|     Wrapped { | ||||
|         name: String, | ||||
|         trace: Box<Trace>, | ||||
|     }, | ||||
| } | ||||
| 
 | ||||
| pub struct Traced<A> { | ||||
|     a: A, | ||||
|     t: Box<Trace>, | ||||
| } | ||||
| 
 | ||||
| trait WithTrace: Sized { | ||||
|     fn with_trace(self, t: Box<Trace>) -> Traced<Self>; | ||||
| } | ||||
| 
 | ||||
| impl<A> WithTrace for A { | ||||
|     fn with_trace(self, t: Box<Trace>) -> Traced<Self> { | ||||
|         Traced { a: self, t } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Trace { | ||||
|     fn pure() -> Box<Self> { | ||||
|         Self::Pure.into() | ||||
|     } | ||||
| 
 | ||||
|     fn resolution() -> Box<Self> { | ||||
|         Self::InvolvesOneResolution.into() | ||||
|     } | ||||
| 
 | ||||
|     fn event(event: &str) -> Box<Self> { | ||||
|         Self::Event(event.into()).into() | ||||
|     } | ||||
| 
 | ||||
|     fn wrapped(self: Box<Self>, event: &str) -> Box<Self> { | ||||
|         Self::Wrapped { | ||||
|             name: event.into(), | ||||
|             trace: self, | ||||
|         } | ||||
|         .into() | ||||
|     } | ||||
| 
 | ||||
|     fn after(self: Box<Self>, t: Box<Self>) -> Box<Self> { | ||||
|         match (*self, *t) { | ||||
|             (Self::Pure, a) => a.into(), | ||||
|             (a, Self::Pure) => a.into(), | ||||
|             (a, b) => Self::Sequential { | ||||
|                 first: b.into(), | ||||
|                 second: a.into(), | ||||
|             } | ||||
|             .into(), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn before(self: Box<Self>, t: Box<Self>) -> Box<Self> { | ||||
|         match (*self, *t) { | ||||
|             (Self::Pure, a) => a.into(), | ||||
|             (a, Self::Pure) => a.into(), | ||||
|             (a, b) => Self::Sequential { | ||||
|                 first: a.into(), | ||||
|                 second: b.into(), | ||||
|             } | ||||
|             .into(), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn parallel(ta: Box<Self>, tb: Box<Self>) -> Box<Self> { | ||||
|         match (*ta, *tb) { | ||||
|             (Self::Pure, a) => a.into(), | ||||
|             (a, Self::Pure) => a.into(), | ||||
|             (a, b) => Self::Parallel(a.into(), b.into()).into(), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn length(&self) -> usize { | ||||
|         match self { | ||||
|             Self::Pure => 0, | ||||
|             Self::InvolvesOneResolution => 1, | ||||
|             Self::Event(_) => 0, | ||||
|             Self::Parallel(a, b) => max(a.length(), b.length()), | ||||
|             Self::Sequential { first, second } => first.length() + second.length(), | ||||
|             Self::Wrapped { name: _, trace } => trace.length(), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn width(&self) -> usize { | ||||
|         match self { | ||||
|             Self::Pure => 0, | ||||
|             Self::InvolvesOneResolution => 1, | ||||
|             Self::Event(_) => 0, | ||||
|             Self::Parallel(a, b) => a.width() + b.width(), | ||||
|             Self::Sequential { first, second } => max(first.width(), second.width()), | ||||
|             Self::Wrapped { name: _, trace } => trace.width(), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<A> Traced<A> { | ||||
|     fn wrapped(self, event: &str) -> Self { | ||||
|         Traced { | ||||
|             a: self.a, | ||||
|             t: self.t.wrapped(event), | ||||
|         } | ||||
|     } | ||||
|     fn after(self, t: Box<Trace>) -> Self { | ||||
|         Traced { | ||||
|             a: self.a, | ||||
|             t: self.t.after(t), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn before(self, t: Box<Trace>) -> Self { | ||||
|         Traced { | ||||
|             a: self.a, | ||||
|             t: self.t.before(t), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn length(&self) -> usize { | ||||
|         self.t.length() | ||||
|     } | ||||
| 
 | ||||
|     pub fn width(&self) -> usize { | ||||
|         self.t.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 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(Trace::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(Trace::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(Trace::parallel(fa.t, fb.t)) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Applicative for TracedClass { | ||||
|     fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> { | ||||
|         a.with_trace(Trace::pure()) | ||||
|     } | ||||
| 
 | ||||
|     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(Trace::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(Trace::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 ibind<'a, A: 'a, B: 'a>( | ||||
|         mut a: A, | ||||
|         mut f: impl 'a + FnMut(A) -> Self::F<'a, IState<A, B>>, | ||||
|     ) -> Self::F<'a, B> | ||||
|     where | ||||
|         Self: 'a, | ||||
|     { | ||||
|         let mut t = Trace::pure(); | ||||
|         loop { | ||||
|             let fa = f(a); | ||||
|             t = fa.t.after(t); | ||||
|             match fa.a { | ||||
|                 IState::Pending(next_a) => a = next_a, | ||||
|                 IState::Done(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) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| struct TracedResolver<'a> { | ||||
|     resolver: Rc<dyn Resolver<'a, TestContextTraced>>, | ||||
| } | ||||
| @ -300,7 +40,7 @@ impl<'a> Resolver<'a, TestContextTraced> for TracedResolver<'a> { | ||||
|             }, | ||||
|             self.resolver.clone().resolve(address), | ||||
|         ) | ||||
|         .after(Trace::resolution()) | ||||
|         .after_resolution() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -314,17 +54,3 @@ impl<'a, A: Mentionable<'a, TestContextTraced>> Traceable<'a> for A { | ||||
|         TypelessMentionable::from_typed(self).cast_full(factory, TracedResolver::new) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Diagnostic<TracedClass> for TracedDiagnostic { | ||||
|     fn after<'a, A>(fa: Traced<A>, event: &'a str) -> Traced<A> { | ||||
|         fa.after(Trace::event(event)) | ||||
|     } | ||||
| 
 | ||||
|     fn before<'a, A>(fa: Traced<A>, event: &'a str) -> Traced<A> { | ||||
|         fa.before(Trace::event(event)) | ||||
|     } | ||||
| 
 | ||||
|     fn wrapped<'a, A>(fa: Traced<A>, event: &'a str) -> Traced<A> { | ||||
|         fa.wrapped(event) | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user