版博士V2.0程序
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 

354 rader
9.7 KiB

  1. /**
  2. * The `Ord` type class represents types which support comparisons with a _total order_.
  3. *
  4. * Instances should satisfy the laws of total orderings:
  5. *
  6. * 1. Reflexivity: `S.compare(a, a) <= 0`
  7. * 2. Antisymmetry: if `S.compare(a, b) <= 0` and `S.compare(b, a) <= 0` then `a <-> b`
  8. * 3. Transitivity: if `S.compare(a, b) <= 0` and `S.compare(b, c) <= 0` then `S.compare(a, c) <= 0`
  9. *
  10. * @since 2.0.0
  11. */
  12. import { Contravariant1 } from './Contravariant'
  13. import { Eq } from './Eq'
  14. import { Monoid } from './Monoid'
  15. import { Ordering } from './Ordering'
  16. import { Semigroup } from './Semigroup'
  17. /**
  18. * @category model
  19. * @since 2.0.0
  20. */
  21. export interface Ord<A> extends Eq<A> {
  22. readonly compare: (first: A, second: A) => Ordering
  23. }
  24. /**
  25. * @category defaults
  26. * @since 2.10.0
  27. */
  28. export declare const equalsDefault: <A>(compare: (first: A, second: A) => Ordering) => (x: A, y: A) => boolean
  29. /**
  30. * @category constructors
  31. * @since 2.0.0
  32. */
  33. export declare const fromCompare: <A>(compare: (first: A, second: A) => Ordering) => Ord<A>
  34. /**
  35. * Given a tuple of `Ord`s returns an `Ord` for the tuple.
  36. *
  37. * @example
  38. * import { tuple } from 'fp-ts/Ord'
  39. * import * as B from 'fp-ts/boolean'
  40. * import * as S from 'fp-ts/string'
  41. * import * as N from 'fp-ts/number'
  42. *
  43. * const O = tuple(S.Ord, N.Ord, B.Ord)
  44. * assert.strictEqual(O.compare(['a', 1, true], ['b', 2, true]), -1)
  45. * assert.strictEqual(O.compare(['a', 1, true], ['a', 2, true]), -1)
  46. * assert.strictEqual(O.compare(['a', 1, true], ['a', 1, false]), 1)
  47. *
  48. * @since 2.10.0
  49. */
  50. export declare const tuple: <A extends readonly unknown[]>(...ords: { [K in keyof A]: Ord<A[K]> }) => Ord<Readonly<A>>
  51. /**
  52. * @since 2.10.0
  53. */
  54. export declare const reverse: <A>(O: Ord<A>) => Ord<A>
  55. /**
  56. * A typical use case for `contramap` would be like, given some `User` type, to construct an `Ord<User>`.
  57. *
  58. * We can do so with a function from `User -> X` where `X` is some value that we know how to compare
  59. * for ordering (meaning we have an `Ord<X>`)
  60. *
  61. * For example, given the following `User` type, there are lots of possible choices for `X`,
  62. * but let's say we want to sort a list of users by `lastName`.
  63. *
  64. * If we have a way of comparing `lastName`s for ordering (`ordLastName: Ord<string>`) and we know how to go from `User -> string`,
  65. * using `contramap` we can do this
  66. *
  67. * @example
  68. * import { pipe } from 'fp-ts/function'
  69. * import { contramap, Ord } from 'fp-ts/Ord'
  70. * import * as RA from 'fp-ts/ReadonlyArray'
  71. * import * as S from 'fp-ts/string'
  72. *
  73. * interface User {
  74. * readonly firstName: string
  75. * readonly lastName: string
  76. * }
  77. *
  78. * const ordLastName: Ord<string> = S.Ord
  79. *
  80. * const ordByLastName: Ord<User> = pipe(
  81. * ordLastName,
  82. * contramap((user) => user.lastName)
  83. * )
  84. *
  85. * assert.deepStrictEqual(
  86. * RA.sort(ordByLastName)([
  87. * { firstName: 'a', lastName: 'd' },
  88. * { firstName: 'c', lastName: 'b' }
  89. * ]),
  90. * [
  91. * { firstName: 'c', lastName: 'b' },
  92. * { firstName: 'a', lastName: 'd' }
  93. * ]
  94. * )
  95. *
  96. * @since 2.0.0
  97. */
  98. export declare const contramap: <A, B>(f: (b: B) => A) => (fa: Ord<A>) => Ord<B>
  99. /**
  100. * @category type lambdas
  101. * @since 2.0.0
  102. */
  103. export declare const URI = 'Ord'
  104. /**
  105. * @category type lambdas
  106. * @since 2.0.0
  107. */
  108. export declare type URI = typeof URI
  109. declare module './HKT' {
  110. interface URItoKind<A> {
  111. readonly [URI]: Ord<A>
  112. }
  113. }
  114. /**
  115. * A typical use case for the `Semigroup` instance of `Ord` is merging two or more orderings.
  116. *
  117. * For example the following snippet builds an `Ord` for a type `User` which
  118. * sorts by `created` date descending, and **then** `lastName`
  119. *
  120. * @example
  121. * import * as D from 'fp-ts/Date'
  122. * import { pipe } from 'fp-ts/function'
  123. * import { contramap, getSemigroup, Ord, reverse } from 'fp-ts/Ord'
  124. * import * as RA from 'fp-ts/ReadonlyArray'
  125. * import * as S from 'fp-ts/string'
  126. *
  127. * interface User {
  128. * readonly id: string
  129. * readonly lastName: string
  130. * readonly created: Date
  131. * }
  132. *
  133. * const ordByLastName: Ord<User> = pipe(
  134. * S.Ord,
  135. * contramap((user) => user.lastName)
  136. * )
  137. *
  138. * const ordByCreated: Ord<User> = pipe(
  139. * D.Ord,
  140. * contramap((user) => user.created)
  141. * )
  142. *
  143. * const ordUserByCreatedDescThenLastName = getSemigroup<User>().concat(
  144. * reverse(ordByCreated),
  145. * ordByLastName
  146. * )
  147. *
  148. * assert.deepStrictEqual(
  149. * RA.sort(ordUserByCreatedDescThenLastName)([
  150. * { id: 'c', lastName: 'd', created: new Date(1973, 10, 30) },
  151. * { id: 'a', lastName: 'b', created: new Date(1973, 10, 30) },
  152. * { id: 'e', lastName: 'f', created: new Date(1980, 10, 30) }
  153. * ]),
  154. * [
  155. * { id: 'e', lastName: 'f', created: new Date(1980, 10, 30) },
  156. * { id: 'a', lastName: 'b', created: new Date(1973, 10, 30) },
  157. * { id: 'c', lastName: 'd', created: new Date(1973, 10, 30) }
  158. * ]
  159. * )
  160. *
  161. * @category instances
  162. * @since 2.0.0
  163. */
  164. export declare const getSemigroup: <A = never>() => Semigroup<Ord<A>>
  165. /**
  166. * Returns a `Monoid` such that:
  167. *
  168. * - its `concat(ord1, ord2)` operation will order first by `ord1`, and then by `ord2`
  169. * - its `empty` value is an `Ord` that always considers compared elements equal
  170. *
  171. * @example
  172. * import { sort } from 'fp-ts/Array'
  173. * import { contramap, reverse, getMonoid } from 'fp-ts/Ord'
  174. * import * as S from 'fp-ts/string'
  175. * import * as B from 'fp-ts/boolean'
  176. * import { pipe } from 'fp-ts/function'
  177. * import { concatAll } from 'fp-ts/Monoid'
  178. * import * as N from 'fp-ts/number'
  179. *
  180. * interface User {
  181. * readonly id: number
  182. * readonly name: string
  183. * readonly age: number
  184. * readonly rememberMe: boolean
  185. * }
  186. *
  187. * const byName = pipe(
  188. * S.Ord,
  189. * contramap((p: User) => p.name)
  190. * )
  191. *
  192. * const byAge = pipe(
  193. * N.Ord,
  194. * contramap((p: User) => p.age)
  195. * )
  196. *
  197. * const byRememberMe = pipe(
  198. * B.Ord,
  199. * contramap((p: User) => p.rememberMe)
  200. * )
  201. *
  202. * const M = getMonoid<User>()
  203. *
  204. * const users: Array<User> = [
  205. * { id: 1, name: 'Guido', age: 47, rememberMe: false },
  206. * { id: 2, name: 'Guido', age: 46, rememberMe: true },
  207. * { id: 3, name: 'Giulio', age: 44, rememberMe: false },
  208. * { id: 4, name: 'Giulio', age: 44, rememberMe: true }
  209. * ]
  210. *
  211. * // sort by name, then by age, then by `rememberMe`
  212. * const O1 = concatAll(M)([byName, byAge, byRememberMe])
  213. * assert.deepStrictEqual(sort(O1)(users), [
  214. * { id: 3, name: 'Giulio', age: 44, rememberMe: false },
  215. * { id: 4, name: 'Giulio', age: 44, rememberMe: true },
  216. * { id: 2, name: 'Guido', age: 46, rememberMe: true },
  217. * { id: 1, name: 'Guido', age: 47, rememberMe: false }
  218. * ])
  219. *
  220. * // now `rememberMe = true` first, then by name, then by age
  221. * const O2 = concatAll(M)([reverse(byRememberMe), byName, byAge])
  222. * assert.deepStrictEqual(sort(O2)(users), [
  223. * { id: 4, name: 'Giulio', age: 44, rememberMe: true },
  224. * { id: 2, name: 'Guido', age: 46, rememberMe: true },
  225. * { id: 3, name: 'Giulio', age: 44, rememberMe: false },
  226. * { id: 1, name: 'Guido', age: 47, rememberMe: false }
  227. * ])
  228. *
  229. * @category instances
  230. * @since 2.4.0
  231. */
  232. export declare const getMonoid: <A = never>() => Monoid<Ord<A>>
  233. /**
  234. * @category instances
  235. * @since 2.7.0
  236. */
  237. export declare const Contravariant: Contravariant1<URI>
  238. /**
  239. * @since 2.11.0
  240. */
  241. export declare const trivial: Ord<unknown>
  242. /**
  243. * @since 2.11.0
  244. */
  245. export declare const equals: <A>(O: Ord<A>) => (second: A) => (first: A) => boolean
  246. /**
  247. * Test whether one value is _strictly less than_ another
  248. *
  249. * @since 2.0.0
  250. */
  251. export declare const lt: <A>(O: Ord<A>) => (first: A, second: A) => boolean
  252. /**
  253. * Test whether one value is _strictly greater than_ another
  254. *
  255. * @since 2.0.0
  256. */
  257. export declare const gt: <A>(O: Ord<A>) => (first: A, second: A) => boolean
  258. /**
  259. * Test whether one value is _non-strictly less than_ another
  260. *
  261. * @since 2.0.0
  262. */
  263. export declare const leq: <A>(O: Ord<A>) => (first: A, second: A) => boolean
  264. /**
  265. * Test whether one value is _non-strictly greater than_ another
  266. *
  267. * @since 2.0.0
  268. */
  269. export declare const geq: <A>(O: Ord<A>) => (first: A, second: A) => boolean
  270. /**
  271. * Take the minimum of two values. If they are considered equal, the first argument is chosen
  272. *
  273. * @since 2.0.0
  274. */
  275. export declare const min: <A>(O: Ord<A>) => (first: A, second: A) => A
  276. /**
  277. * Take the maximum of two values. If they are considered equal, the first argument is chosen
  278. *
  279. * @since 2.0.0
  280. */
  281. export declare const max: <A>(O: Ord<A>) => (first: A, second: A) => A
  282. /**
  283. * Clamp a value between a minimum and a maximum
  284. *
  285. * @since 2.0.0
  286. */
  287. export declare const clamp: <A>(O: Ord<A>) => (low: A, hi: A) => (a: A) => A
  288. /**
  289. * Test whether a value is between a minimum and a maximum (inclusive)
  290. *
  291. * @since 2.0.0
  292. */
  293. export declare const between: <A>(O: Ord<A>) => (low: A, hi: A) => (a: A) => boolean
  294. /**
  295. * Use [`tuple`](#tuple) instead.
  296. *
  297. * @category zone of death
  298. * @since 2.0.0
  299. * @deprecated
  300. */
  301. export declare const getTupleOrd: <T extends ReadonlyArray<Ord<any>>>(
  302. ...ords: T
  303. ) => Ord<{
  304. [K in keyof T]: T[K] extends Ord<infer A> ? A : never
  305. }>
  306. /**
  307. * Use [`reverse`](#reverse) instead.
  308. *
  309. * @category zone of death
  310. * @since 2.0.0
  311. * @deprecated
  312. */
  313. export declare const getDualOrd: <A>(O: Ord<A>) => Ord<A>
  314. /**
  315. * Use [`Contravariant`](#contravariant) instead.
  316. *
  317. * @category zone of death
  318. * @since 2.0.0
  319. * @deprecated
  320. */
  321. export declare const ord: Contravariant1<URI>
  322. /**
  323. * Use [`Ord`](./boolean.ts.html#ord) instead.
  324. *
  325. * @category zone of death
  326. * @since 2.0.0
  327. * @deprecated
  328. */
  329. export declare const ordBoolean: Ord<boolean>
  330. /**
  331. * Use [`Ord`](./string.ts.html#ord) instead.
  332. *
  333. * @category zone of death
  334. * @since 2.0.0
  335. * @deprecated
  336. */
  337. export declare const ordString: Ord<string>
  338. /**
  339. * Use [`Ord`](./number.ts.html#ord) instead.
  340. *
  341. * @category zone of death
  342. * @since 2.0.0
  343. * @deprecated
  344. */
  345. export declare const ordNumber: Ord<number>
  346. /**
  347. * Use [`Ord`](./Date.ts.html#ord) instead.
  348. *
  349. * @category zone of death
  350. * @since 2.0.0
  351. * @deprecated
  352. */
  353. export declare const ordDate: Ord<Date>