Skip to content

Instantly share code, notes, and snippets.

@Willmo36
Created May 31, 2019 17:09
Show Gist options
  • Save Willmo36/e15f19c8e7fe603bf97de4b1032210ac to your computer and use it in GitHub Desktop.
Save Willmo36/e15f19c8e7fe603bf97de4b1032210ac to your computer and use it in GitHub Desktop.
First attempt at zio inspiried monad in TypeScript
import { Either, left, right } from "fp-ts/lib/Either";
import { Task, task } from "fp-ts/lib/Task";
type Env<R, E, A> = (r: R) => Task<Either<E, A>>;
const run = <R, E, A>(r: R, env: Env<R, E, A>) => env(r);
const of = <R, E, A>(a: A): Env<R, E, A> =>
(r: R) => task.of(right(a));
const ask = <R>(): Env<R, void, R> =>
(r: R) => task.of(right(r));
const map = <R, E, A, B>(f: (a: A) => B) => (fa: Env<R, E, A>): Env<R, E, B> =>
(r: R) => run(r, fa).map(ea => ea.map(f));
const chain = <R, E, A, B>(fab: (a: A) => Env<R, E, B>, fa: Env<R, E, A>): Env<R, E, B> =>
(r: R) =>
//run fa
//if it success, use the value to run fb
//return as single env
run(r, fa).chain(ea =>
ea.fold(
e => task.of(left<E, B>(e)),
a => run(r, fab(a))
)
)
type ConsoleService = {
writeLine: (s: string) => Env<ConsoleService, void, void>;
readLine: () => Env<ConsoleService, void, string>;
}
const testConsoleService: ConsoleService = {
writeLine: () => of(undefined),
readLine: () => of('hi')
}
type ProgramEnv = ConsoleService;
const program: Env<ProgramEnv, void, string> =
chain(
r => r.readLine(),
ask<ProgramEnv>()
);
//run the env then run the task
run(testConsoleService, program).run().then(result => {
console.log("Result", result);
//Result right("hi")
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment