playground
tcmts.examples.effect.playground · #oygviqe4 · ts file
// tcm: namespace demo
import { catchTag, fail, gen, runPromise, runSync, sleep, succeed } from "#codebase/effect/Effect";
import type { Effect } from "#codebase/effect/Effect";
import { TaggedError } from "#codebase/effect/Data";
import assert from "node:assert/strict";
/** A sum that went over {@link limit}. */
export class Overflow extends TaggedError("Overflow")<{ readonly at: number }> {}
/** The largest sum {@link add} gives. */
export const limit = 100;
/**
* Two numbers added, as an Effect that fails with {@link Overflow} past {@link limit}.
*
* ```ts
* runSync(add(20, 22))
* ```
*/
export const add = (a: number, b: number): Effect<number, Overflow> =>
gen(function* () {
const sum = (yield* succeed(a)) + (yield* succeed(b));
if (sum > limit) return yield* fail(new Overflow({ at: sum }));
return sum;
});
/** {@link add}, with an {@link Overflow} turned into its sum, negated. */
export const addOrNegate = (a: number, b: number): Effect<number> =>
catchTag(add(a, b), "Overflow", (e) => succeed(-e.at));
/** Runs the playground's programs, one of them asynchronously. */
export const main = async () => {
console.log("sync", runSync(add(20, 22)));
console.log("caught", runSync(addOrNegate(60, 70)));
console.log(
"async",
await runPromise(
gen(function* () {
yield* sleep("10 millis");
return "slept";
}),
),
);
};
export const testAdd = () => assert.equal(runSync(add(20, 22)), 42);
export const testOverflowIsCaught = () => assert.equal(runSync(addOrNegate(60, 70)), -130);
used by