rivo
Version:
🤖 The ultimate library you need for composable type-level programming in TypeScript, powered by HKT.
55 lines (49 loc) • 2.1 kB
TypeScript
// @ts-ignore - `Some` and `None` are only used in doc comments
import type { None, Option, Some } from ".";
import type { Map } from "./Map";
import type { GenericReturn1W } from "..";
import type { Args, Fn1, GenericFn, GenericResolver, Param0W, ReturnW } from "../HKT";
import type { Applicative, TypeClass$$Applicative } from "../typeclass";
declare module "../typeclass/Applicative" {
interface ApplicativeImpl {
Option: ImplApplicativeFor<Option, Option$$Applicative>;
}
}
/**
* Implementation of the {@link Applicative} type class for {@link Option}.
*/
export interface Option$$Applicative extends TypeClass$$Applicative<Option> {
Ap: Option$$Applicative$ApFn;
Of: Option$$Applicative$OfFn;
}
type ExtractOption<O extends Option<unknown>> = O extends Option<infer T> ? T : never;
interface ApResolver extends GenericResolver<[Option<Fn1>, Option<unknown>], Option<unknown>> {
on1_: ([fab]: Args<this>) => [
[Param0W<ExtractOption<typeof fab>>],
ReturnW<ExtractOption<typeof fab>>,
];
on_1: ([, f]: Args<this>) => [[Option<Fn1<ExtractOption<typeof f>, unknown>>], Option<unknown>];
on11: ([fab, f]: Args<this>) => [
[],
Option<GenericReturn1W<ExtractOption<typeof fab>, ExtractOption<typeof f>>>,
];
}
/**
* [Fn] Apply an {@link Option} of a function to an {@link Option} of a value if both are
* {@link Some}, otherwise return {@link None}.
*/
interface Option$$Applicative$ApFn extends GenericFn<ApResolver> {
def: ([fab, f]: Args<this>) => Option$$Applicative$Ap<typeof fab, typeof f>;
}
type Option$$Applicative$Ap<FAB extends Option<Fn1>, F extends Option> =
FAB extends Some<infer G extends Fn1<ExtractOption<F>, unknown>> ? Map<G, F> : None;
interface OfResolver extends GenericResolver<[unknown], Option<unknown>> {
on1: ([x]: Args<this>) => [[], Option<typeof x>];
}
/**
* [Fn] Build an {@link Option} from a value (wrapping it in a {@link Some}).
*/
interface Option$$Applicative$OfFn extends GenericFn<OfResolver> {
def: ([x]: Args<this>) => Option$$Applicative$Of<typeof x>;
}
type Option$$Applicative$Of<T> = Some<T>;