rivo
Version:
🤖 The ultimate library you need for composable type-level programming in TypeScript, powered by HKT.
316 lines (292 loc) • 9.51 kB
TypeScript
import type AppendFn from "./Append";
import type AtFn from "./At";
import type ConcatFn from "./Concat";
import type ConcatWFn from "./ConcatW";
import type ContainsFn from "./Contains";
import type CreateFn from "./Create";
import type EveryFn from "./Every";
import type ExtendFn from "./Extend";
import type ExtendLeftFn from "./ExtendLeft";
import type ExtendLeftWFn from "./ExtendLeftW";
import type ExtendWFn from "./ExtendW";
import type FilterFn from "./Filter";
import type FlatMapFn from "./FlatMap";
import type FlattenFn from "./Flatten";
import type FoldLFn from "./FoldL";
import type FoldRFn from "./FoldR";
import type HeadFn from "./Head";
import type InitFn from "./Init";
import type IsListFn from "./IsList";
import type { JoinFn } from "./Join";
import type LastFn from "./Last";
import type MapFn from "./Map";
import type PrependFn from "./Prepend";
import type RangeOfFn from "./RangeOf";
import type RejectFn from "./Reject";
import type ReverseFn from "./Reverse";
import type SumFn from "./Sum";
import type TailFn from "./Tail";
import type ToUnionFn from "./ToUnion";
import type { Fn1, Fn2, Param0, PartialApply } from "../HKT";
import type { Nat } from "../Num";
// @ts-ignore - Only used in doc comments
import type { Tuple$$Of1 } from "../Tuple";
import type { Lazied, Lazied$Get } from "../helpers";
import type { Show } from "../typeclass/Show";
/**
* Alias for `readonly T[]` to represent a tuple type.
*/
export type List<T = unknown> = readonly T[];
/**
* Lazied version of {@link List}.
*/
export interface ListL<L extends Lazied> extends List<Lazied$Get<L>> {}
/**
* Alias for `readonly [T, U]`.
*/
export type Pair<T, U> = readonly [T, U];
/***********
* Methods *
***********/
/**
* Methods for tuples.
*/
export namespace List {
/**
* [Fn] Apply a function to each element of a {@link List} (i.e., fixed-length tuple).
*
* Sig: `<T, U>[f: (x: T) => U](xs: List<T>) => List<U>`
*/
export type Map<F extends Fn1> = PartialApply<MapFn, [F]>;
/**
* [Fn] Filter a {@link List} (i.e., fixed-length tuple) based on a predicate.
*
* Sig: `<T>(pred: (x: T) => boolean) => (xs: List<T>) => List<T>`
*
* @see {@link Reject} for the opposite.
*/
export type Filter<Pred extends Fn1<never, boolean>> = PartialApply<FilterFn, [Pred]>;
/**
* [Fn] Keep elements of a {@link List} (i.e., fixed-length tuple) that do not
* satisfy a predicate.
*
* Sig: `<T>[pred: (x: T) => boolean](xs: List<T>) => List<T>`
*
* @see {@link Filter} for the opposite.
*/
export type Reject<Pred extends Fn1<never, boolean>> = PartialApply<RejectFn, [Pred]>;
/**
* [Fn] Determine if every element in a {@link List} (i.e., fixed-length tuple)
* satisfies a predicate.
*
* Sig: `<T>[pred: (x: T) => boolean](xs: List<T>) => boolean`
*/
export type Every<Pred extends Fn1<never, boolean>> = PartialApply<EveryFn, [Pred]>;
/**
* [Fn] Apply a function to each element of a {@link List} (i.e., fixed-length tuple)
* and concatenate the results.
*
* Sig: `<T, U>[f: (x: T) => List<U>](xs: List<T>) => List<U>`
*/
export type FlatMap<F extends Fn1<never, List>> = PartialApply<FlatMapFn, [F]>;
/**
* [Fn] Flatten a {@link List} of {@link List}s into a single {@link List}.
*
* Sig: `<T>(xs: List<List<T>>) => List<T>`
*/
export type Flatten = FlattenFn;
/**
* [Fn] Apply a binary function to each element of a {@link List} (i.e., fixed-length
* tuple), starting from the **left**. The result of the previous application is passed as the
* first argument to the next application.
*
* The **L** suffix stands for “**L**eft”.
*
* Sig: `<T, U>[f: (acc: U, x: T) => U, init: U](xs: List<T>) => U`
*/
export type FoldL<F extends Fn2, I extends Param0<F>> = PartialApply<FoldLFn, [F, I]>;
/**
* [Fn] Apply a binary function to each element of a {@link List} (i.e., fixed-length
* tuple), starting from the **right**. The result of the previous application is passed as the
* first argument to the next application.
*
* The **R** suffix stands for “**R**ight”.
*
* Sig: `<T, U>[f: (acc: U, x: T) => U, init: U](xs: List<T>) => U`
*/
export type FoldR<F extends Fn2, I extends Param0<F>> = PartialApply<FoldRFn, [F, I]>;
/**
* [Fn] Calculate the sum of a {@link List} of {@link Int}s.
*
* Sig: `(ns: List<Int>) => Int`
*/
export type Sum = SumFn;
/**
* [Fn] Check if a {@link List} contains a specific element.
*
* Sig: `<T>[x: T](xs: List<T>) => boolean`
*/
export type Contains<T> = PartialApply<ContainsFn, [T]>;
/**
* [Fn] Reverse a {@link List}.
*
* Sig: `<T>(xs: List<T>) => List<T>`
*/
export type Reverse = ReverseFn;
/**
* [Fn] Get the element at a specific index in a {@link List}.
*
* Sig: `<T>[i: Nat](xs: List<T>) => Option<T>`
*/
export type At<I extends Nat> = PartialApply<AtFn, [I]>;
/**
* [Fn] Get the first element in a {@link List}.
*
* Sig: `<T>(xs: List<T>) => Option<T>`
*/
export type Head = HeadFn;
/**
* [Fn] Get all elements in a {@link List} except the first one.
*
* Sig: `<T>(xs: List<T>) => Option<List<T>>`
*/
export type Tail = TailFn;
/**
* [Fn] Get all elements in a {@link List} except the last one.
*
* Sig: `<T>(xs: List<T>) => Option<List<T>>`
*/
export type Init = InitFn;
/**
* [Fn] Get the last element in a {@link List}.
*
* Sig: `<T>(xs: List<T>) => Option<T>`
*/
export type Last = LastFn;
/**
* [Fn] Concatenate two {@link List}s.
*
* Sig: `<T>(xs: List<T>, ys: List<T>) => List<T>`
*/
export type Concat = ConcatFn;
/**
* [Fn] Less strict version of {@link Concat}. The **W** suffix (short for
* **W**idening) means that both {@link List}s can hold different types.
*
* Sig: `<T, U>(xs: List<T>, ys: List<U>) => List<T | U>`
*/
export type ConcatW = ConcatWFn;
/**
* [Fn] Extend a {@link List} by concatenating another {@link List} on the **right**.
*
* Sig: `<T>[ys: List<T>](xs: List<T>) => List<T>`
*
* @see {@link ExtendLeft} for the opposite.
*/
export type Extend<US extends List> = PartialApply<ExtendFn, [US]>;
/**
* [Fn] Less strict version of {@link Extend}.The **W** suffix (short for **W**idening) means that
* both {@link List}s can hold different types.
*
* Sig: `<T, U>[ys: List<U>](xs: List<T>) => List<T | U>`
*
* @see {@link ExtendLeftW} for the opposite.
*/
export type ExtendW<US extends List> = PartialApply<ExtendWFn, [US]>;
/**
* [Fn] Extend a {@link List} by concatenating another {@link List} on the **left**.
*
* Sig: `<T>[ys: List<T>](xs: List<T>) => List<T>`
*
* @see {@link Extend} for the opposite.
*/
export type ExtendLeft<US extends List> = PartialApply<ExtendLeftFn, [US]>;
/**
* [Fn] Less strict version of {@link ExtendLeft}.The **W** suffix (short for **W**idening) means
* that both {@link List}s can hold different types.
*
* It is actually an alias of {@link ConcatW}.
*
* Sig: `<T, U>[ys: List<U>](xs: List<T>) => List<T | U>`
*
* @see {@link ExtendW} for the opposite.
*/
export type ExtendLeftW<US extends List> = PartialApply<ExtendLeftWFn, [US]>;
/**
* [Fn] Append an element to a {@link List} (i.e., fixed-length tuple).
*
* Sig: `<T>[x: T](xs: List<T>) => List<T>`
*/
export type Append<T> = PartialApply<AppendFn, [T]>;
/**
* [Fn] Prepend an element to a {@link List} (i.e., fixed-length tuple).
*
* Sig: `<T>[x: T](xs: List<T>) => List<T>`
*/
export type Prepend<T> = PartialApply<PrependFn, [T]>;
/**
* [Fn] Join a {@link List} of {@link Show}s into a single string.
*
* Sig: `[sep: Show](xs: List<Show>) => string`
*/
export type Join<Sep extends Show> = PartialApply<JoinFn, [Sep]>;
/**
* [Fn] Convert a {@link List} to a union type.
*
* Sig: `<T>(xs: List<T>) => T`
*/
export type ToUnion = ToUnionFn;
}
/******************
* Static members *
******************/
/**
* [Fn] Create a {@link List} with one element.
*
* Sig: `<T>(x: T) => List<T>`
*
* @example
* ```typescript
* type R1 = $<List$$Create, 1>;
* // ^?: readonly [1]
* type R2 = $<List$$Create, "foo" | false>;
* // ^?: readonly ["foo" | false]
* ```
*
* @see {@link Tuple$$Of1} if you want a version with more precise function signature.
*/
export type List$$Create = CreateFn;
/**
* [Fn] Check if a value is a {@link List} (i.e., fixed-length tuple).
*
* Sig: `(x: unknown) => boolean`
*
* @example
* ```typescript
* type R1 = $<List$$IsList, readonly [1, 2, 3]>;
* // ^?: true
* type R2 = $<List$$IsList, [1, 2, 3, 4]>;
* // ^?: true
* type R3 = $<List$$IsList, readonly []>;
* // ^?: true
* type R4 = $<List$$IsList, string[]>;
* // ^?: false
* type R5 = $<List$$IsList, readonly [1, 2, 3, ...number[]]>;
* // ^?: false
* ```
*/
export type List$$IsList = IsListFn;
/**
* [Fn] Generate a {@link List} of numbers from `From` to `To` (exclusive).
*
* Sig: `(from: Int, to: Int) => List<Int>`
*/
export type List$$RangeOf = RangeOfFn;
/****************
* Type classes *
****************/
export type { List$$HKT$$Builder, List$$HKT$$Extractor } from "./HKT";
export type { List$$Applicative } from "./Applicative";
export type { List$$Functor } from "./Functor";
export type { List$$Monad } from "./Monad";
export type { List$$Semigroup } from "./Semigroup";