summaryrefslogtreecommitdiff
path: root/u/types/fn/optional.ts
diff options
context:
space:
mode:
Diffstat (limited to 'u/types/fn/optional.ts')
-rw-r--r--u/types/fn/optional.ts93
1 files changed, 0 insertions, 93 deletions
diff --git a/u/types/fn/optional.ts b/u/types/fn/optional.ts
deleted file mode 100644
index 504e496..0000000
--- a/u/types/fn/optional.ts
+++ /dev/null
@@ -1,93 +0,0 @@
-import { type Mapper, Predicate, type Supplier, Tagged, isTagged } from '@emprespresso/pengueno';
-
-export type MaybeGiven<T> = T | undefined | null;
-
-export const IOptionalTag = 'IOptional' as const;
-export type IOptionalTag = typeof IOptionalTag;
-export const isOptional = <T>(o: unknown): o is IOptional<T> => isTagged(o, IOptionalTag);
-export class IOptionalEmptyError extends Error {}
-export interface IOptional<t, T extends NonNullable<t> = NonNullable<t>> extends Tagged<IOptionalTag>, Iterable<T> {
- readonly move: <_T>(t: MaybeGiven<_T>) => IOptional<_T>;
- readonly map: <_T>(mapper: Mapper<T, MaybeGiven<_T>>) => IOptional<_T>;
- readonly filter: (mapper: Predicate<T>) => IOptional<T>;
- readonly flatMap: <_T>(mapper: Mapper<T, MaybeGiven<IOptional<_T>>>) => IOptional<_T>;
- readonly orSome: (supplier: Supplier<MaybeGiven<t>>) => IOptional<T>;
- readonly get: Supplier<T>;
- readonly present: Supplier<boolean>;
-}
-
-type OSomeTag = typeof OSomeTag;
-const OSomeTag = 'O.Some' as const;
-interface Some<T> extends Tagged<OSomeTag> {
- value: NonNullable<T>;
-}
-
-const ONoneTag = 'O.None' as const;
-type ONoneTag = typeof ONoneTag;
-interface None extends Tagged<ONoneTag> {}
-
-const isNone = (o: unknown): o is None => isTagged(o, ONoneTag);
-const isSome = <T>(o: unknown): o is Some<T> => isTagged(o, OSomeTag);
-
-class _Tagged implements Tagged<IOptionalTag> {
- protected constructor(public readonly _tag = IOptionalTag) {}
-}
-
-export class Optional<t, T extends NonNullable<t> = NonNullable<t>> extends _Tagged implements IOptional<T> {
- private constructor(private readonly self: Some<T> | None) {
- super();
- }
-
- public move<_T>(t: MaybeGiven<_T>): IOptional<_T> {
- return this.map(() => t);
- }
-
- public orSome(supplier: Supplier<MaybeGiven<t>>): IOptional<T> {
- if (isNone(this.self)) return Optional.from(supplier());
- return this;
- }
-
- public get(): T {
- if (isNone(this.self)) throw new IOptionalEmptyError('called get() on None optional');
- return this.self.value;
- }
-
- public filter(mapper: Predicate<T>): IOptional<T> {
- if (isNone(this.self) || !mapper(this.self.value)) return Optional.none();
- return Optional.some(this.self.value);
- }
-
- public map<_T>(mapper: Mapper<T, MaybeGiven<_T>>): IOptional<_T> {
- if (isNone(this.self)) return Optional.none();
- return Optional.from(mapper(this.self.value)) as IOptional<_T>;
- }
-
- public flatMap<_T>(mapper: Mapper<T, MaybeGiven<IOptional<_T>>>): IOptional<_T> {
- if (isNone(this.self)) return Optional.none();
- return Optional.from(mapper(this.self.value))
- .orSome(() => Optional.none())
- .get();
- }
-
- public present() {
- return isSome(this.self);
- }
-
- *[Symbol.iterator]() {
- if (isSome(this.self)) yield this.self.value;
- }
-
- static some<t, T extends NonNullable<t> = NonNullable<t>>(value: T): IOptional<T> {
- return new Optional({ value, _tag: OSomeTag });
- }
-
- private static readonly _none = new Optional({ _tag: ONoneTag });
- static none<T>(): IOptional<T> {
- return this._none as unknown as IOptional<T>;
- }
-
- static from<t, T extends NonNullable<t> = NonNullable<t>>(value: MaybeGiven<t>): IOptional<T> {
- if (value === null || value === undefined) return Optional.none<T>();
- return Optional.some(<T>value);
- }
-}