resulty
Version:
A disjunction implementation in TypeScript.
1 lines • 12.5 kB
Source Map (JSON)
{"version":3,"sources":["/Users/rbell/Development/resulty/dist/index.cjs","../src/index.ts"],"names":[],"mappings":"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","file":"/Users/rbell/Development/resulty/dist/index.cjs","sourcesContent":[null,"export interface Catamorphism<E, A, B> {\n Err: (_: E) => B;\n Ok: (_: A) => B;\n}\n\n\nexport interface Err<E> {\n kind: 'err';\n error: E;\n}\n\nexport interface Ok<A> {\n kind: 'ok';\n value: A;\n}\n\n/**\n * A Result represents a computation that may succeed or fail. Ok<T> represents\n * a successful computation, while Err<E> represents a failure.\n */\nexport class Result<E, A> {\n /**\n * Construct a successful result\n * @param value a value to wrap in Ok\n * @returns a new Result with the value wrapped in Ok\n */\n public static ok<E, A>(value: A): Result<E, A> {\n return new Result<E, A>({ kind: 'ok', value });\n }\n\n /**\n * Construct a failed result\n * @param error a value to wrap in Err\n * @returns a new Result with the value wrapped in Err\n */\n public static err<E, A>(error: E): Result<E, A> {\n return new Result<E, A>({ kind: 'err', error });\n }\n\n /**\n * Returns true if the result is a success\n */\n public isOk(): this is Result<E, A> & { state: Ok<A> } {\n return this.state.kind === 'ok';\n }\n\n /**\n * Returns true if the result is a failure\n */\n public isErr(): this is Result<E, A> & { state: Err<E> } {\n return this.state.kind === 'err';\n }\n\n /**\n * Returns the value from a successful result. For an error, returns the\n * result of evaluating the fn\n */\n public getOrElse(fn: () => A): A {\n switch (this.state.kind) {\n case 'ok':\n return this.state.value;\n case 'err':\n return fn();\n }\n }\n\n /**\n * Returns the value from a successful result. Returns the defaultValue if\n * the result was a failure.\n */\n public getOrElseValue(defaultValue: A): A {\n switch (this.state.kind) {\n case 'ok':\n return this.state.value;\n case 'err':\n return defaultValue;\n }\n }\n\n /**\n * Returns a new result after applying fn to the value stored in a successful\n * result. If the result was a failure, then the Err result is simply\n * returned.\n */\n public map<B>(fn: (_: A) => B): Result<E, B> {\n switch (this.state.kind) {\n case 'ok':\n return Result.ok<E, B>(fn(this.state.value));\n case 'err':\n return Result.err<E, B>(this.state.error);\n }\n }\n\n /**\n * An alias for `map`\n */\n public and<B>(fn: (_: A) => B): Result<E, B> {\n return this.map(fn);\n }\n\n /**\n * Returns a new result after applying fn to the error value. successful\n * results are returned unchanged.\n */\n public mapError<X>(fn: (_: E) => X): Result<X, A> {\n switch (this.state.kind) {\n case 'ok':\n return Result.ok<X, A>(this.state.value);\n case 'err':\n return Result.err<X, A>(fn(this.state.error));\n }\n }\n\n /**\n * Chains together two computations that return results. If the result is a\n * success, then the second computation is run. Otherwise, the Err is\n * returned.\n */\n public andThen<B>(fn: (_: A) => Result<E, B>): Result<E, B> {\n switch (this.state.kind) {\n case 'ok':\n return fn(this.state.value);\n case 'err':\n return Result.err<E, B>(this.state.error);\n }\n }\n\n /**\n * Runs an alternative computation in the case that the first computation\n * resulted in an Err.\n */\n public orElse<X>(fn: (_: E) => Result<X, A>): Result<X, A> {\n switch (this.state.kind) {\n case 'ok':\n return Result.ok<X, A>(this.state.value);\n case 'err':\n return fn(this.state.error);\n }\n }\n\n /**\n * Folds over types; a switch/case for success or failure.\n */\n public cata<B>(matcher: Catamorphism<E, A, B>): B {\n switch (this.state.kind) {\n case 'ok':\n return matcher.Ok(this.state.value);\n case 'err':\n return matcher.Err(this.state.error);\n }\n }\n\n /**\n * Encapsulates a common pattern of needing to build up an Object from\n * a series of Result values. This is often solved by nesting `andThen` calls\n * and then completing the chain with a call to `ok`.\n *\n * This feature was inspired (and the code lifted from) this article:\n * https://medium.com/@dhruvrajvanshi/simulating-haskells-do-notation-in-typescript-e48a9501751c\n *\n * Wrapped values are converted to an Object using the Object constructor\n * before assigning. Primitives won't fail at runtime, but results may\n * be unexpected.\n */\n public assign<K extends string, B>(\n k: K,\n other: Result<E, B> | ((a: A) => Result<E, B>)\n ): Result<E, A & { [k in K]: B }> {\n const state = this.state;\n switch (state.kind) {\n case 'ok': {\n const result = typeof other === 'function' ? other(state.value) : other;\n return result.map<A & { [k in K]: B }>(b => ({\n ...Object(state.value),\n [k.toString()]: b,\n }));\n }\n case 'err':\n return Result.err<E, A & { [k in K]: B }>(state.error);\n }\n }\n\n /**\n * Inject a side-effectual operation into a chain of Result computations.\n *\n * The primary use case for `do` is to perform logging in the middle of a flow\n * of Results.\n *\n * The side effect only runs when there isn't an error (Ok).\n *\n * The value will (should) remain unchanged during the `do` operation.\n *\n * ok({})\n * .assign('foo', ok(42))\n * .assign('bar', ok('hello'))\n * .do(scope => console.log('Scope: ', JSON.stringify(scope)))\n * .map(doSomethingElse)\n *\n */\n public do(fn: (a: A) => void): Result<E, A> {\n switch (this.state.kind) {\n case 'ok':\n fn(this.state.value);\n return this;\n case 'err':\n return this;\n }\n }\n\n /**\n * Inject a side-effectual operation into a chain of Result computations.\n *\n * The side effect only runs when there is an error (Err).\n *\n * The value will remain unchanged during the `elseDo` operation.\n *\n * ok({})\n * .assign('foo', ok(42))\n * .assign('bar', err('hello'))\n * .elseDo(scope => console.log('Scope: ', JSON.stringify(scope)))\n * .map(doSomethingElse)\n *\n */\n public elseDo(fn: (err: E) => void): Result<E, A> {\n switch (this.state.kind) {\n case 'ok':\n return this;\n case 'err':\n fn(this.state.error);\n return this;\n }\n }\n\n private constructor(public readonly state: Err<E> | Ok<A>) {}\n}\n\nexport function ok<E, A>(value: A): Result<E, A> {\n return Result.ok<E, A>(value);\n}\n\nexport function err<E, A>(error: E): Result<E, A> {\n return Result.err<E, A>(error);\n}\n\nexport function isOk<E, A>(result: Result<E, A>): result is Result<E, A> & { state: Ok<A> } {\n return result.isOk();\n}\n\nexport function isErr<E, A>(result: Result<E, A>): result is Result<E, A> & { state: Err<E> } {\n return result.isErr();\n}\n"]}