Skip to content

Instantly share code, notes, and snippets.

@RichieAHB
Last active December 19, 2017 09:28
Show Gist options
  • Save RichieAHB/65c5e46430e6596668a8dfcd0056f3af to your computer and use it in GitHub Desktop.
Save RichieAHB/65c5e46430e6596668a8dfcd0056f3af to your computer and use it in GitHub Desktop.
An attempt at understanding and implementing a naive model for algebraic effects in JS.
const Effect = (type, val) => ({ type, val });
const run = gen => {
let r;
while (!(r = gen.next()).done) {}
return r.value;
};
function* handle(fn, map = {}) {
const gen = fn();
let r;
let matchVal = undefined;
while (!(r = gen.next(matchVal)).done) {
if (r.value) {
const matchFn = map[r.value.type];
if (matchFn) {
matchVal = matchFn(r.value.val);
} else {
yield r.value;
}
}
}
return r.value;
}
// Pseudo state
let state = 1;
// The "app";
const runner = handle(
function*() {
const number = yield* handle(
function*() {
const current = yield Effect("State", 1);
yield Effect("Print", "Hello, world!");
return current;
},
// "Pattern matching"
{
State: val => {
state += val;
return state;
}
}
);
return number + 1;
},
{
Print: val => console.log(`Print: ${val}`)
}
);
const output = run(runner);
console.log(output);
/*
OUTPUT
-> Print: Hello, world!
-> 3
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment