From d51c9d74857aca3c2f172609297266968bc7f809 Mon Sep 17 00:00:00 2001 From: Elizabeth Alexander Hunt Date: Mon, 12 May 2025 09:40:12 -0700 Subject: The big refactor TM --- u/trace/itrace.ts | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 u/trace/itrace.ts (limited to 'u/trace/itrace.ts') diff --git a/u/trace/itrace.ts b/u/trace/itrace.ts new file mode 100644 index 0000000..e6189d3 --- /dev/null +++ b/u/trace/itrace.ts @@ -0,0 +1,107 @@ +import type { Mapper, SideEffect, Supplier } from "@emprespresso/pengueno"; + +// the "thing" every Trace writer must "trace()" +type BaseTraceWith = string; +export type ITraceWith = BaseTraceWith | T; +export interface ITrace { + addTrace: Mapper, ITrace>; + trace: SideEffect>; +} + +export type ITraceableTuple = [T, BaseTraceWith | TraceWith]; +export type ITraceableMapper< + T, + U, + TraceWith, + W = ITraceable, +> = ( + w: W, +) => U; + +export interface ITraceable { + readonly trace: ITrace; + get: Supplier; + move: (u: U) => ITraceable; + map: ( + mapper: ITraceableMapper, + ) => ITraceable; + bimap: ( + mapper: ITraceableMapper< + T, + ITraceableTuple | Trace>, + Trace + >, + ) => ITraceable; + peek: (peek: ITraceableMapper) => ITraceable; + flatMap: ( + mapper: ITraceableMapper, Trace>, + ) => ITraceable; + flatMapAsync( + mapper: ITraceableMapper>, Trace>, + ): ITraceable, Trace>; +} + +export class TraceableImpl implements ITraceable { + protected constructor( + private readonly item: T, + public readonly trace: ITrace, + ) {} + + public map( + mapper: ITraceableMapper, + ) { + const result = mapper(this); + return new TraceableImpl(result, this.trace); + } + + public flatMap( + mapper: ITraceableMapper< + T, + ITraceable, + TraceWith + >, + ): ITraceable { + return mapper(this); + } + + public flatMapAsync( + mapper: ITraceableMapper< + T, + Promise>, + TraceWith + >, + ): ITraceable, TraceWith> { + return new TraceableImpl( + mapper(this).then((t) => t.get()), + this.trace, + ); + } + + public peek(peek: ITraceableMapper) { + peek(this); + return this; + } + + public move(t: Tt): ITraceable { + return this.map(() => t); + } + + public bimap( + mapper: ITraceableMapper< + T, + ITraceableTuple | TraceWith>, + TraceWith + >, + ) { + const [item, trace] = mapper(this); + const traces = Array.isArray(trace) ? trace : [trace]; + return new TraceableImpl( + item, + traces.reduce((trace, _trace) => trace.addTrace(_trace), this.trace), + ); + } + + public get() { + return this.item; + } +} -- cgit v1.2.3-70-g09d2