/** * inspired by https://github.com/tusharmath/qio/pull/22 (revised) */ export class GenSTM { readonly _R!: () => R readonly _E!: () => E readonly _A!: () => A constructor(readonly stm: STM) {} *[Symbol.iterator](): Generator, A, any> { return yield this } } const adapter = (_: any, __?: any) => { return new GenSTM(_) } /** * Do simulation using Generators * * @tsplus static effect/core/stm/STM.Ops gen */ export function gen, AEff>( f: (i: { (_: STM): GenSTM }) => Generator ): STM< [Eff] extends [{ _R: () => infer R }] ? R : never, [Eff] extends [{ _E: () => infer E }] ? E : never, AEff > { return STM.suspend(() => { const iterator = f(adapter as any) const state = iterator.next() function run( state: IteratorYieldResult | IteratorReturnResult ): STM { if (state.done) { return STM.succeed(state.value) } return state.value["stm"].flatMap((val) => { const next = iterator.next(val) return run(next) }) } return run(state) }) }