diff options
Diffstat (limited to 'u/trace/itrace.ts')
-rw-r--r-- | u/trace/itrace.ts | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/u/trace/itrace.ts b/u/trace/itrace.ts new file mode 100644 index 0000000..b483067 --- /dev/null +++ b/u/trace/itrace.ts @@ -0,0 +1,72 @@ +import { Mapper, SideEffect } from "../fn/mod.ts"; + +export interface ITrace<TracingW> { + addTrace: Mapper<TracingW, ITrace<TracingW>>; + trace: SideEffect<TracingW>; +} + +export type ITraceableTuple<T, Trace> = [T, Trace]; +export type ITraceableMapper<T, Trace, U, W = ITraceable<T, Trace>> = ( + w: W, +) => U; + +export interface ITraceable<T, Trace> { + readonly item: T; + readonly trace: ITrace<Trace>; + + move<U>(u: U): ITraceable<U, Trace>; + map: <U>( + mapper: ITraceableMapper<T, Trace, U>, + ) => ITraceable<U, Trace>; + bimap: <U>( + mapper: ITraceableMapper<T, Trace, ITraceableTuple<U, Trace>>, + ) => ITraceable<U, Trace>; + peek: (peek: ITraceableMapper<T, Trace, void>) => ITraceable<T, Trace>; + flatMap: <U>( + mapper: ITraceableMapper<T, Trace, ITraceable<U, Trace>>, + ) => ITraceable<U, Trace>; + flatMapAsync<U>( + mapper: ITraceableMapper<T, Trace, Promise<ITraceable<U, Trace>>>, + ): ITraceable<Promise<U>, Trace>; +} + +export class TraceableImpl<T, L> implements ITraceable<T, L> { + protected constructor( + readonly item: T, + readonly trace: ITrace<L>, + ) {} + + public map<U>(mapper: ITraceableMapper<T, L, U>) { + const result = mapper(this); + return new TraceableImpl(result, this.trace); + } + + public flatMap<U>( + mapper: ITraceableMapper<T, L, ITraceable<U, L>>, + ): ITraceable<U, L> { + return mapper(this); + } + + public flatMapAsync<U>( + mapper: ITraceableMapper<T, L, Promise<ITraceable<U, L>>>, + ): ITraceable<Promise<U>, L> { + return new TraceableImpl( + mapper(this).then(({ item }) => item), + this.trace, + ); + } + + public peek(peek: ITraceableMapper<T, L, void>) { + peek(this); + return this; + } + + public move<Tt>(t: Tt): ITraceable<Tt, L> { + return this.map(() => t); + } + + public bimap<U>(mapper: ITraceableMapper<T, L, ITraceableTuple<U, L>>) { + const [item, trace] = mapper(this); + return new TraceableImpl(item, this.trace.addTrace(trace)); + } +} |