Last active
July 18, 2018 09:41
-
-
Save kana-sama/387ebe03e75717652dddbb3a612a160d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @flow | |
interface Command<A> { | |
run(): A; | |
} | |
class Call<A> implements Command<A> { | |
value: () => A; | |
constructor<X>(f: X => A, x: X) { | |
this.value = () => f(x); | |
} | |
run(): A { | |
return this.value(); | |
} | |
} | |
interface Saga<A> { | |
run(): A; | |
map<B>(f: (A) => B): Saga<B>; | |
chain<B>(next: (A) => Saga<B>): Saga<B>; | |
} | |
class Pure<A> implements Saga<A> { | |
value: A; | |
constructor(value: A) { | |
this.value = value; | |
} | |
run(): A { | |
return this.value; | |
} | |
map<B>(f: A => B): Saga<B> { | |
return new Pure(f(this.value)); | |
} | |
chain<B>(next: A => Saga<B>): Saga<B> { | |
return next(this.value); | |
} | |
} | |
class Next<A> implements Saga<A> { | |
next: () => Saga<A>; | |
constructor(next: () => Saga<A>) { | |
this.next = next; | |
} | |
static fromCommand(command: Command<A>): Saga<A> { | |
return new Next(() => new Pure(command.run())); | |
} | |
run(): A { | |
return this.next().run(); | |
} | |
map<B>(f: A => B): Saga<B> { | |
return new Next(() => this.next().map(f)); | |
} | |
chain<B>(next: A => Saga<B>): Saga<B> { | |
return new Next(() => next(this.next().run())); | |
} | |
} | |
function inc(x: number): number { | |
return x + 1; | |
} | |
function numberToString(x: number): string { | |
return `Number(${x})`; | |
} | |
console.log( | |
new Pure(10) | |
.chain(x => | |
Next.fromCommand(new Call(inc, x)) | |
.chain(y => Next.fromCommand(new Call(numberToString, y))) | |
.map(y => `Before: ${x}, After: ${y}`), | |
) | |
.run(), | |
); // Number(11) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment