UNPKG

fp-ts

Version:

Functional programming in TypeScript

226 lines (225 loc) 6.06 kB
/** * The `Ord` type class represents types which support comparisons with a _total order_. * * Instances should satisfy the laws of total orderings: * * 1. Reflexivity: `S.compare(a, a) <= 0` * 2. Antisymmetry: if `S.compare(a, b) <= 0` and `S.compare(b, a) <= 0` then `a <-> b` * 3. Transitivity: if `S.compare(a, b) <= 0` and `S.compare(b, c) <= 0` then `S.compare(a, c) <= 0` * * @since 2.0.0 */ import { Contravariant1 } from './Contravariant' import { Eq } from './Eq' import { Monoid } from './Monoid' import { Ordering } from './Ordering' import { Semigroup } from './Semigroup' /** * @category type classes * @since 2.0.0 */ export interface Ord<A> extends Eq<A> { readonly compare: (x: A, y: A) => Ordering } /** * @category instances * @since 2.0.0 */ export declare const ordString: Ord<string> /** * @category instances * @since 2.0.0 */ export declare const ordNumber: Ord<number> /** * @category instances * @since 2.0.0 */ export declare const ordBoolean: Ord<boolean> /** * Test whether one value is _strictly less than_ another * * @since 2.0.0 */ export declare function lt<A>(O: Ord<A>): (x: A, y: A) => boolean /** * Test whether one value is _strictly greater than_ another * * @since 2.0.0 */ export declare function gt<A>(O: Ord<A>): (x: A, y: A) => boolean /** * Test whether one value is _non-strictly less than_ another * * @since 2.0.0 */ export declare function leq<A>(O: Ord<A>): (x: A, y: A) => boolean /** * Test whether one value is _non-strictly greater than_ another * * @since 2.0.0 */ export declare function geq<A>(O: Ord<A>): (x: A, y: A) => boolean /** * Take the minimum of two values. If they are considered equal, the first argument is chosen * * @since 2.0.0 */ export declare function min<A>(O: Ord<A>): (x: A, y: A) => A /** * Take the maximum of two values. If they are considered equal, the first argument is chosen * * @since 2.0.0 */ export declare function max<A>(O: Ord<A>): (x: A, y: A) => A /** * Clamp a value between a minimum and a maximum * * @since 2.0.0 */ export declare function clamp<A>(O: Ord<A>): (low: A, hi: A) => (x: A) => A /** * Test whether a value is between a minimum and a maximum (inclusive) * * @since 2.0.0 */ export declare function between<A>(O: Ord<A>): (low: A, hi: A) => (x: A) => boolean /** * @category constructors * @since 2.0.0 */ export declare function fromCompare<A>(compare: (x: A, y: A) => Ordering): Ord<A> /** * Use `getMonoid` instead * * @category instances * @since 2.0.0 * @deprecated */ export declare function getSemigroup<A = never>(): Semigroup<Ord<A>> /** * Returns a `Monoid` such that: * * - its `concat(ord1, ord2)` operation will order first by `ord1`, and then by `ord2` * - its `empty` value is an `Ord` that always considers compared elements equal * * @example * import { sort } from 'fp-ts/Array' * import { contramap, getDualOrd, getMonoid, ordBoolean, ordNumber, ordString } from 'fp-ts/Ord' * import { pipe } from 'fp-ts/function' * import { fold } from 'fp-ts/Monoid' * * interface User { * id: number * name: string * age: number * rememberMe: boolean * } * * const byName = pipe( * ordString, * contramap((p: User) => p.name) * ) * * const byAge = pipe( * ordNumber, * contramap((p: User) => p.age) * ) * * const byRememberMe = pipe( * ordBoolean, * contramap((p: User) => p.rememberMe) * ) * * const M = getMonoid<User>() * * const users: Array<User> = [ * { id: 1, name: 'Guido', age: 47, rememberMe: false }, * { id: 2, name: 'Guido', age: 46, rememberMe: true }, * { id: 3, name: 'Giulio', age: 44, rememberMe: false }, * { id: 4, name: 'Giulio', age: 44, rememberMe: true } * ] * * // sort by name, then by age, then by `rememberMe` * const O1 = fold(M)([byName, byAge, byRememberMe]) * assert.deepStrictEqual(sort(O1)(users), [ * { id: 3, name: 'Giulio', age: 44, rememberMe: false }, * { id: 4, name: 'Giulio', age: 44, rememberMe: true }, * { id: 2, name: 'Guido', age: 46, rememberMe: true }, * { id: 1, name: 'Guido', age: 47, rememberMe: false } * ]) * * // now `rememberMe = true` first, then by name, then by age * const O2 = fold(M)([getDualOrd(byRememberMe), byName, byAge]) * assert.deepStrictEqual(sort(O2)(users), [ * { id: 4, name: 'Giulio', age: 44, rememberMe: true }, * { id: 2, name: 'Guido', age: 46, rememberMe: true }, * { id: 3, name: 'Giulio', age: 44, rememberMe: false }, * { id: 1, name: 'Guido', age: 47, rememberMe: false } * ]) * * @category instances * @since 2.4.0 */ export declare function getMonoid<A = never>(): Monoid<Ord<A>> /** * Given a tuple of `Ord`s returns an `Ord` for the tuple * * @example * import { getTupleOrd, ordString, ordNumber, ordBoolean } from 'fp-ts/Ord' * * const O = getTupleOrd(ordString, ordNumber, ordBoolean) * assert.strictEqual(O.compare(['a', 1, true], ['b', 2, true]), -1) * assert.strictEqual(O.compare(['a', 1, true], ['a', 2, true]), -1) * assert.strictEqual(O.compare(['a', 1, true], ['a', 1, false]), 1) * * @category instances * @since 2.0.0 */ export declare function getTupleOrd<T extends ReadonlyArray<Ord<any>>>( ...ords: T ): Ord< { [K in keyof T]: T[K] extends Ord<infer A> ? A : never } > /** * @category combinators * @since 2.0.0 */ export declare function getDualOrd<A>(O: Ord<A>): Ord<A> /** * @category Contravariant * @since 2.0.0 */ export declare const contramap: <A, B>(f: (b: B) => A) => (fa: Ord<A>) => Ord<B> /** * @category instances * @since 2.0.0 */ export declare const URI = 'Ord' /** * @category instances * @since 2.0.0 */ export declare type URI = typeof URI declare module './HKT' { interface URItoKind<A> { readonly [URI]: Ord<A> } } /** * @category instances * @since 2.0.0 */ export declare const ordDate: Ord<Date> /** * @category instances * @since 2.7.0 */ export declare const Contravariant: Contravariant1<URI> /** * @category instances * @since 2.0.0 */ export declare const ord: Contravariant1<URI>