Skip to content

Instantly share code, notes, and snippets.

@canonic-epicure
Created June 30, 2020 12:31
Show Gist options
  • Save canonic-epicure/ceeb117115702bf494643baeef279c32 to your computer and use it in GitHub Desktop.
Save canonic-epicure/ceeb117115702bf494643baeef279c32 to your computer and use it in GitHub Desktop.
type Effect = { kind : string }
type EffectHandler<E extends Effect> = (e : E) => unknown
function runGeneratorSyncWithEffect<ResultT, YieldT extends Effect, ArgsT extends any[]> (
effectHandler : EffectHandler<YieldT>,
func : (...args : ArgsT) => Generator<YieldT, ResultT, any>,
args : ArgsT,
scope? : any
) : ResultT
{
const gen = func.apply(scope || null, args)
let iteration = gen.next()
while (!iteration.done) {
iteration = gen.next(effectHandler(iteration.value))
}
return iteration.value
}
type EffectStateGet = { kind : 'state_get' }
type EffectStateSet = { kind : 'state_set', value : number }
const effectfulFunction = function * () : Generator<EffectStateGet | EffectStateSet, void, { value : number }> {
const state = yield { kind : 'state_get' }
yield { kind : 'state_set', value : ++state.value }
}
const state = { value : 0 }
const effectHandler : EffectHandler<EffectStateGet | EffectStateSet> = e => {
switch (e.kind) {
case 'state_get':
return state
case 'state_set':
return state.value = e.value
}
}
runGeneratorSyncWithEffect(
effectHandler,
effectfulFunction,
[],
null
)
console.log(state.value) // 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment