EdgeAIG's picture
download
raw
6.67 kB
/**
* Works with values that may be `undefined`.
*
* Use this module for plain TypeScript values of type `A | undefined` when
* `undefined` is the only absence marker. It is a small alternative to wrapping
* values in `Option` when your data already uses `undefined` to mean "no
* value". The module includes helpers for mapping defined values, matching both
* cases, throwing when a value is missing, adapting throwing functions, and
* building reducers or combiners.
*
* @since 4.0.0
*/
import * as Combiner from "./Combiner.js";
import { dual } from "./Function.js";
import * as Reducer from "./Reducer.js";
/**
* Maps a defined value with `f`, or returns `undefined` unchanged.
*
* **When to use**
*
* Use to apply a pure transformation to an `A | undefined` value while
* preserving `undefined` as absence.
*
* @see {@link match} when you need to handle the `undefined` case explicitly
*
* @category mapping
* @since 4.0.0
*/
export const map = /*#__PURE__*/dual(2, (self, f) => self === undefined ? undefined : f(self));
/**
* Pattern matches on an `A | undefined` value, running `onDefined` when the
* value is present or evaluating `onUndefined` when the value is `undefined`.
*
* **When to use**
*
* Use when you need to turn an `A | undefined` into a non-optional result by
* handling both the defined and undefined branches in one expression.
*
* @see {@link map} for transforming defined values while preserving `undefined`
* @see {@link getOrThrowWith} for throwing when the value is `undefined` instead of returning a fallback branch
*
* @category pattern matching
* @since 4.0.0
*/
export const match = /*#__PURE__*/dual(2, (self, {
onDefined,
onUndefined
}) => self === undefined ? onUndefined() : onDefined(self));
/**
* Returns the defined value, or throws the value produced by `onUndefined`
* when the input is `undefined`.
*
* **When to use**
*
* Use when you need fail-fast unwrapping of an `A | undefined` value and want
* to provide the thrown error for the undefined case.
*
* **Details**
*
* Defined values are returned unchanged. When the input is `undefined`,
* `onUndefined` is called and its result is thrown.
*
* @see {@link getOrThrow} for the default-error sibling
* @see {@link match} for handling defined and undefined cases without throwing
*
* @category getters
* @since 4.0.0
*/
export const getOrThrowWith = /*#__PURE__*/dual(2, (self, onUndefined) => {
if (self !== undefined) {
return self;
}
throw onUndefined();
});
/**
* Returns the defined value, or throws a default `Error` when the input is
* `undefined`.
*
* **When to use**
*
* Use when you need to unwrap a value that should already be defined and a
* generic missing-value `Error` is acceptable.
*
* **Details**
*
* Defined inputs are returned unchanged. `undefined` throws
* `new Error("getOrThrow called on a undefined")`.
*
* @see {@link getOrThrowWith} for the sibling that lets callers choose the thrown value
* @see {@link match} for handling defined and undefined cases without throwing
*
* @category getters
* @since 4.0.0
*/
export const getOrThrow = /*#__PURE__*/getOrThrowWith(() => new Error("getOrThrow called on a undefined"));
/**
* Converts a throwing function into one that returns successful results
* unchanged and returns `undefined` when the function throws.
*
* **When to use**
*
* Use to adapt exception-throwing functions when `undefined` is the absence
* value you want to return for failures.
*
* **Gotchas**
*
* Thrown values are discarded. If the wrapped function can successfully return
* `undefined`, that success is indistinguishable from a thrown failure.
*
* @category converting
* @since 4.0.0
*/
export const liftThrowable = f => (...a) => {
try {
return f(...a);
} catch {
return undefined;
}
};
/**
* Creates a `Reducer` for `UndefinedOr<A>` that prioritizes the first non-`undefined`
* value and combines values when both operands are present.
*
* **When to use**
*
* Use when you need to reduce values that may be `undefined`, keeping the
* first defined value as a fallback and combining only when both operands are
* defined.
*
* **Details**
*
* Combining `undefined` with `undefined` returns `undefined`. Combining a
* defined value with `undefined` keeps the defined value, so the first defined
* value wins when only one side is present. When both values are defined, they
* are combined with `combiner.combine`. The reducer's initial value is
* `undefined`.
*
* @category constructors
* @since 4.0.0
*/
export function makeReducer(combiner) {
return Reducer.make((self, that) => {
if (self === undefined) return that;
if (that === undefined) return self;
return combiner.combine(self, that);
}, undefined);
}
/**
* Creates a `Combiner` for `A | undefined` that combines values only when both
* operands are defined.
*
* **When to use**
*
* Use to lift a `Combiner` so any `undefined` operand makes the combined result
* `undefined`.
*
* **Details**
*
* - `undefined` combined with any value returns `undefined`
* - Any value combined with `undefined` returns `undefined`
* - `a` combined with `b` returns `combiner.combine(a, b)`
*
* @see {@link makeReducerFailFast} if you have a `Reducer` and want to lift it
* to `UndefinedOr` values.
*
* @category constructors
* @since 4.0.0
*/
export function makeCombinerFailFast(combiner) {
return Combiner.make((self, that) => {
if (self === undefined || that === undefined) return undefined;
return combiner.combine(self, that);
});
}
/**
* Creates a `Reducer` for `A | undefined` by wrapping an existing reducer with
* fail-fast semantics.
*
* **When to use**
*
* Use to wrap an existing `Reducer` so any `undefined` value aborts the entire
* reduction result.
*
* **Details**
*
* - Initial value is the wrapped reducer's `initialValue`
* - Combining two defined values delegates to the wrapped reducer
* - If the accumulator or next value is `undefined`, the reduction returns `undefined`
*
* @see {@link makeCombinerFailFast} if you only have a `Combiner` and want to
* lift it to `UndefinedOr` values.
*
* @category constructors
* @since 4.0.0
*/
export function makeReducerFailFast(reducer) {
const combine = makeCombinerFailFast(reducer).combine;
const initialValue = reducer.initialValue;
return Reducer.make(combine, initialValue, collection => {
let out = initialValue;
for (const value of collection) {
out = combine(out, value);
if (out === undefined) return out;
}
return out;
});
}
//# sourceMappingURL=UndefinedOr.js.map

Xet Storage Details

Size:
6.67 kB
·
Xet hash:
59597b67f6cab308ce2932138f7eadd0897e13a7ff1d8a99d4537d76e62e1fea

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.