export class GenEval {
readonly _A!: () => A
constructor(readonly io: Eval) {}
*[Symbol.iterator](): Generator, A, any> {
return yield this
}
}
function adapter(_: Eval): GenEval {
return new GenEval(_)
}
function run_, AEff>(
state: IteratorYieldResult | IteratorReturnResult,
iterator: Generator
): Eval {
if (state.done) {
return Eval.succeed(state.value)
}
return state.value["io"].flatMap((val) => {
const next = iterator.next(val)
return run_(next, iterator)
})
}
/**
* Generator
*
* @tsplus static Eval.Ops gen
*/
export function gen, AEff>(
f: (i: { (_: Eval): GenEval }) => Generator
): Eval {
return Eval.suspend(() => {
const iterator = f(adapter)
const state = iterator.next()
return run_(state, iterator)
})
}