From c5c70ab99ce4566a154e66a74c9bed9f0085abb4 Mon Sep 17 00:00:00 2001 From: rowan Date: Thu, 11 Sep 2025 00:28:11 -0400 Subject: [PATCH] add new option/result methods --- src/option.js | 114 ++++++++++++++++++++++++++++++++++---------------- src/result.js | 58 +++++++++++++++++++++---- 2 files changed, 126 insertions(+), 46 deletions(-) diff --git a/src/option.js b/src/option.js index 90d7bbd..abbcaea 100644 --- a/src/option.js +++ b/src/option.js @@ -105,33 +105,24 @@ export class Some extends Option { * @param {(value: T) => Option} fn * @returns {Option} */ - bind(fn) { + andThen(fn) { return fn(this.#value) } - /** - * @template V - * @param {(value: T) => V} fn - * @returns {Option} - */ - map(fn) { - return new Some(fn(this.#value)) - } - /** * @param {Option} other * @returns {Option} */ - alt(_other) { - return this + and(other) { + return other } /** - * @param {Some} other - * @returns {Some} + * @param {Option} other + * @returns {Option} */ - and(other) { - return other + or(_other) { + return this } /** @@ -188,6 +179,35 @@ export class Some extends Option { } } + /** + * @template V + * @param {(value: T) => V} fn + * @returns {Option} + */ + map(fn) { + return new Some(fn(this.#value)) + } + + /** + * @template V + * @param {V} _default + * @param {(value: T) => V} fn + * @returns {V} + */ + mapOr(_default, fn) { + return this.map(fn) + } + + /** + * @template V + * @param {() => V} _defaultFn + * @param {(value: T) => V} fn + * @returns {V} + */ + mapOrElse(_defaultFn, fn) { + return this.map(fn) + } + /** * @template E * @param {E} _err @@ -263,21 +283,20 @@ class _None extends Option { /** * @template T - * @template {Option} R - * @param {(value: T) => R} fn - * @returns {R} + * @param {Option} _other + * @returns {Option} */ - bind(_fn) { + and(_other) { return this } /** - * @template V + * @template T * @template {Option} R - * @param {(value: T) => V} fn + * @param {(value: T) => R} fn * @returns {R} */ - map(_fn) { + andThen(_fn) { return this } @@ -286,7 +305,7 @@ class _None extends Option { * @param {Option} other * @returns {Option} */ - alt(other) { + or(other) { return other } @@ -299,15 +318,6 @@ class _None extends Option { return fn() } - /** - * @template T - * @param {Some} _other - * @returns {Some} - */ - and(_other) { - return this - } - /** * @template T * @param {(value: T) => bool} _predicate @@ -353,6 +363,36 @@ class _None extends Option { flatten() { return this } + + /** + * @template V + * @template {Option} R + * @param {(value: T) => V} fn + * @returns {R} + */ + map(_fn) { + return this + } + + /** + * @template V + * @param {V} defaultValue + * @param {(value: T) => V} _fn + * @returns {V} + */ + mapOr(defaultValue, _fn) { + return defaultValue + } + + /** + * @template V + * @param {() => V} defaultFn + * @param {(value: T) => V} _fn + * @returns {V} + */ + mapOrElse(defaultFn, _fn) { + return defaultFn() + } /** * @template T, E @@ -429,10 +469,10 @@ implementor(Some) .implements(...structures) .specifiedBy(FantasyLand) .with({ - chain: Some.prototype.bind, + chain: Some.prototype.andThen, filter: Some.prototype.filter, map: Some.prototype.map, - alt: Some.prototype.alt, + alt: Some.prototype.or, equals: Some.prototype.equals, lte: Some.prototype.lte, }) @@ -441,10 +481,10 @@ implementor(_None) .implements(...structures) .specifiedBy(FantasyLand) .with({ - chain: _None.prototype.bind, + chain: _None.prototype.andThen, filter: _None.prototype.filter, map: _None.prototype.map, - alt: _None.prototype.alt, + alt: _None.prototype.or, equals: _None.prototype.equals, lte: _None.prototype.lte, }) diff --git a/src/result.js b/src/result.js index 5f7b9ba..7d4e451 100644 --- a/src/result.js +++ b/src/result.js @@ -75,7 +75,7 @@ export class Ok extends Result { * @param {(value: T) => R} fn * @returns {R} */ - bind(fn) { + andThen(fn) { return fn(this.#value) } @@ -89,6 +89,26 @@ export class Ok extends Result { return Result.ok(fn(this.#value)) } + /** + * @template V + * @param {V} _defaultValue + * @param {(value: T) => V} fn + * @returns {V} + */ + mapOr(_defaultValue, fn) { + return this.map(fn) + } + + /** + * @template V + * @param {() => V} _defaultFn + * @param {(value: T) => V} fn + * @returns {V} + */ + mapOr(_defaultFn, fn) { + return this.map(fn) + } + /** * @template E * @param {Result} other @@ -103,7 +123,7 @@ export class Ok extends Result { * @param {Result} other * @returns {Result} */ - alt(_other) { + or(_other) { return this } @@ -249,20 +269,40 @@ export class Err extends Result { * @param {(value: T) => R} fn * @returns {R} */ - bind(_fn) { + andThen(_fn) { return this } /** * @template V, E * @template {Result} R - * @param {(value: T) => V} fn + * @param {(value: T) => V} _fn * @returns {R} */ map(_fn) { return this } + /** + * @template V + * @param {V} defaultValue + * @param {(value: T) => V} _fn + * @returns {V} + */ + mapOr(defaultValue, _fn) { + return defaultValue + } + + /** + * @template V + * @param {() => V} defaultFn + * @param {(value: T) => V} _fn + * @returns {V} + */ + mapOrElse(defaultFn, _fn) { + return defaultFn() + } + /** * @template T * @param {Result} _other @@ -277,7 +317,7 @@ export class Err extends Result { * @param {Result} other * @returns {Result} */ - alt(other) { + or(other) { return other } @@ -405,10 +445,10 @@ implementor(Ok) .implements(...structures) .specifiedBy(FantasyLand) .with({ - chain: Ok.prototype.bind, + chain: Ok.prototype.andThen, map: Ok.prototype.map, reduce: Ok.prototype.reduce, - alt: Ok.prototype.alt, + alt: Ok.prototype.or, equals: Ok.prototype.equals, lte: Ok.prototype.lte, }) @@ -417,10 +457,10 @@ implementor(Err) .implements(...structures) .specifiedBy(FantasyLand) .with({ - chain: Err.prototype.bind, + chain: Err.prototype.andThen, map: Err.prototype.map, reduce: Err.prototype.reduce, - alt: Err.prototype.alt, + alt: Err.prototype.or, equals: Err.prototype.equals, lte: Err.prototype.lte, })