add new option/result methods

This commit is contained in:
Rowan 2025-09-11 00:28:11 -04:00
parent 1ccb2b1b1c
commit c5c70ab99c
2 changed files with 126 additions and 46 deletions

View file

@ -105,33 +105,24 @@ export class Some extends Option {
* @param {(value: T) => Option<T>} fn * @param {(value: T) => Option<T>} fn
* @returns {Option<T>} * @returns {Option<T>}
*/ */
bind(fn) { andThen(fn) {
return fn(this.#value) return fn(this.#value)
} }
/**
* @template V
* @param {(value: T) => V} fn
* @returns {Option<V>}
*/
map(fn) {
return new Some(fn(this.#value))
}
/** /**
* @param {Option<T>} other * @param {Option<T>} other
* @returns {Option<T>} * @returns {Option<T>}
*/ */
alt(_other) { and(other) {
return this return other
} }
/** /**
* @param {Some<T>} other * @param {Option<T>} other
* @returns {Some<T>} * @returns {Option<T>}
*/ */
and(other) { or(_other) {
return other return this
} }
/** /**
@ -188,6 +179,35 @@ export class Some extends Option {
} }
} }
/**
* @template V
* @param {(value: T) => V} fn
* @returns {Option<V>}
*/
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 * @template E
* @param {E} _err * @param {E} _err
@ -263,21 +283,20 @@ class _None extends Option {
/** /**
* @template T * @template T
* @template {Option<T>} R * @param {Option<T>} _other
* @param {(value: T) => R} fn * @returns {Option<T>}
* @returns {R}
*/ */
bind(_fn) { and(_other) {
return this return this
} }
/** /**
* @template V * @template T
* @template {Option<T>} R * @template {Option<T>} R
* @param {(value: T) => V} fn * @param {(value: T) => R} fn
* @returns {R} * @returns {R}
*/ */
map(_fn) { andThen(_fn) {
return this return this
} }
@ -286,7 +305,7 @@ class _None extends Option {
* @param {Option<T>} other * @param {Option<T>} other
* @returns {Option<T>} * @returns {Option<T>}
*/ */
alt(other) { or(other) {
return other return other
} }
@ -299,15 +318,6 @@ class _None extends Option {
return fn() return fn()
} }
/**
* @template T
* @param {Some<T>} _other
* @returns {Some<T>}
*/
and(_other) {
return this
}
/** /**
* @template T * @template T
* @param {(value: T) => bool} _predicate * @param {(value: T) => bool} _predicate
@ -353,6 +363,36 @@ class _None extends Option {
flatten() { flatten() {
return this return this
} }
/**
* @template V
* @template {Option<T>} 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 * @template T, E
@ -429,10 +469,10 @@ implementor(Some)
.implements(...structures) .implements(...structures)
.specifiedBy(FantasyLand) .specifiedBy(FantasyLand)
.with({ .with({
chain: Some.prototype.bind, chain: Some.prototype.andThen,
filter: Some.prototype.filter, filter: Some.prototype.filter,
map: Some.prototype.map, map: Some.prototype.map,
alt: Some.prototype.alt, alt: Some.prototype.or,
equals: Some.prototype.equals, equals: Some.prototype.equals,
lte: Some.prototype.lte, lte: Some.prototype.lte,
}) })
@ -441,10 +481,10 @@ implementor(_None)
.implements(...structures) .implements(...structures)
.specifiedBy(FantasyLand) .specifiedBy(FantasyLand)
.with({ .with({
chain: _None.prototype.bind, chain: _None.prototype.andThen,
filter: _None.prototype.filter, filter: _None.prototype.filter,
map: _None.prototype.map, map: _None.prototype.map,
alt: _None.prototype.alt, alt: _None.prototype.or,
equals: _None.prototype.equals, equals: _None.prototype.equals,
lte: _None.prototype.lte, lte: _None.prototype.lte,
}) })

View file

@ -75,7 +75,7 @@ export class Ok extends Result {
* @param {(value: T) => R} fn * @param {(value: T) => R} fn
* @returns {R} * @returns {R}
*/ */
bind(fn) { andThen(fn) {
return fn(this.#value) return fn(this.#value)
} }
@ -89,6 +89,26 @@ export class Ok extends Result {
return Result.ok(fn(this.#value)) 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 * @template E
* @param {Result<T, E>} other * @param {Result<T, E>} other
@ -103,7 +123,7 @@ export class Ok extends Result {
* @param {Result<T, E>} other * @param {Result<T, E>} other
* @returns {Result<T, E>} * @returns {Result<T, E>}
*/ */
alt(_other) { or(_other) {
return this return this
} }
@ -249,20 +269,40 @@ export class Err extends Result {
* @param {(value: T) => R} fn * @param {(value: T) => R} fn
* @returns {R} * @returns {R}
*/ */
bind(_fn) { andThen(_fn) {
return this return this
} }
/** /**
* @template V, E * @template V, E
* @template {Result<V, E>} R * @template {Result<V, E>} R
* @param {(value: T) => V} fn * @param {(value: T) => V} _fn
* @returns {R} * @returns {R}
*/ */
map(_fn) { map(_fn) {
return this 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 * @template T
* @param {Result<T, E>} _other * @param {Result<T, E>} _other
@ -277,7 +317,7 @@ export class Err extends Result {
* @param {Result<T, E>} other * @param {Result<T, E>} other
* @returns {Result<T, E>} * @returns {Result<T, E>}
*/ */
alt(other) { or(other) {
return other return other
} }
@ -405,10 +445,10 @@ implementor(Ok)
.implements(...structures) .implements(...structures)
.specifiedBy(FantasyLand) .specifiedBy(FantasyLand)
.with({ .with({
chain: Ok.prototype.bind, chain: Ok.prototype.andThen,
map: Ok.prototype.map, map: Ok.prototype.map,
reduce: Ok.prototype.reduce, reduce: Ok.prototype.reduce,
alt: Ok.prototype.alt, alt: Ok.prototype.or,
equals: Ok.prototype.equals, equals: Ok.prototype.equals,
lte: Ok.prototype.lte, lte: Ok.prototype.lte,
}) })
@ -417,10 +457,10 @@ implementor(Err)
.implements(...structures) .implements(...structures)
.specifiedBy(FantasyLand) .specifiedBy(FantasyLand)
.with({ .with({
chain: Err.prototype.bind, chain: Err.prototype.andThen,
map: Err.prototype.map, map: Err.prototype.map,
reduce: Err.prototype.reduce, reduce: Err.prototype.reduce,
alt: Err.prototype.alt, alt: Err.prototype.or,
equals: Err.prototype.equals, equals: Err.prototype.equals,
lte: Err.prototype.lte, lte: Err.prototype.lte,
}) })