版博士V2.0程序
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 

449 satır
13 KiB

  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.ordDate = exports.ordNumber = exports.ordString = exports.ordBoolean = exports.ord = exports.getDualOrd = exports.getTupleOrd = exports.between = exports.clamp = exports.max = exports.min = exports.geq = exports.leq = exports.gt = exports.lt = exports.equals = exports.trivial = exports.Contravariant = exports.getMonoid = exports.getSemigroup = exports.URI = exports.contramap = exports.reverse = exports.tuple = exports.fromCompare = exports.equalsDefault = void 0;
  4. var Eq_1 = require("./Eq");
  5. var function_1 = require("./function");
  6. // -------------------------------------------------------------------------------------
  7. // defaults
  8. // -------------------------------------------------------------------------------------
  9. /**
  10. * @category defaults
  11. * @since 2.10.0
  12. */
  13. var equalsDefault = function (compare) {
  14. return function (first, second) {
  15. return first === second || compare(first, second) === 0;
  16. };
  17. };
  18. exports.equalsDefault = equalsDefault;
  19. // -------------------------------------------------------------------------------------
  20. // constructors
  21. // -------------------------------------------------------------------------------------
  22. /**
  23. * @category constructors
  24. * @since 2.0.0
  25. */
  26. var fromCompare = function (compare) { return ({
  27. equals: (0, exports.equalsDefault)(compare),
  28. compare: function (first, second) { return (first === second ? 0 : compare(first, second)); }
  29. }); };
  30. exports.fromCompare = fromCompare;
  31. // -------------------------------------------------------------------------------------
  32. // combinators
  33. // -------------------------------------------------------------------------------------
  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. var tuple = function () {
  51. var ords = [];
  52. for (var _i = 0; _i < arguments.length; _i++) {
  53. ords[_i] = arguments[_i];
  54. }
  55. return (0, exports.fromCompare)(function (first, second) {
  56. var i = 0;
  57. for (; i < ords.length - 1; i++) {
  58. var r = ords[i].compare(first[i], second[i]);
  59. if (r !== 0) {
  60. return r;
  61. }
  62. }
  63. return ords[i].compare(first[i], second[i]);
  64. });
  65. };
  66. exports.tuple = tuple;
  67. /**
  68. * @since 2.10.0
  69. */
  70. var reverse = function (O) { return (0, exports.fromCompare)(function (first, second) { return O.compare(second, first); }); };
  71. exports.reverse = reverse;
  72. /* istanbul ignore next */
  73. var contramap_ = function (fa, f) { return (0, function_1.pipe)(fa, (0, exports.contramap)(f)); };
  74. /**
  75. * A typical use case for `contramap` would be like, given some `User` type, to construct an `Ord<User>`.
  76. *
  77. * We can do so with a function from `User -> X` where `X` is some value that we know how to compare
  78. * for ordering (meaning we have an `Ord<X>`)
  79. *
  80. * For example, given the following `User` type, there are lots of possible choices for `X`,
  81. * but let's say we want to sort a list of users by `lastName`.
  82. *
  83. * If we have a way of comparing `lastName`s for ordering (`ordLastName: Ord<string>`) and we know how to go from `User -> string`,
  84. * using `contramap` we can do this
  85. *
  86. * @example
  87. * import { pipe } from 'fp-ts/function'
  88. * import { contramap, Ord } from 'fp-ts/Ord'
  89. * import * as RA from 'fp-ts/ReadonlyArray'
  90. * import * as S from 'fp-ts/string'
  91. *
  92. * interface User {
  93. * readonly firstName: string
  94. * readonly lastName: string
  95. * }
  96. *
  97. * const ordLastName: Ord<string> = S.Ord
  98. *
  99. * const ordByLastName: Ord<User> = pipe(
  100. * ordLastName,
  101. * contramap((user) => user.lastName)
  102. * )
  103. *
  104. * assert.deepStrictEqual(
  105. * RA.sort(ordByLastName)([
  106. * { firstName: 'a', lastName: 'd' },
  107. * { firstName: 'c', lastName: 'b' }
  108. * ]),
  109. * [
  110. * { firstName: 'c', lastName: 'b' },
  111. * { firstName: 'a', lastName: 'd' }
  112. * ]
  113. * )
  114. *
  115. * @since 2.0.0
  116. */
  117. var contramap = function (f) { return function (fa) {
  118. return (0, exports.fromCompare)(function (first, second) { return fa.compare(f(first), f(second)); });
  119. }; };
  120. exports.contramap = contramap;
  121. /**
  122. * @category type lambdas
  123. * @since 2.0.0
  124. */
  125. exports.URI = 'Ord';
  126. /**
  127. * A typical use case for the `Semigroup` instance of `Ord` is merging two or more orderings.
  128. *
  129. * For example the following snippet builds an `Ord` for a type `User` which
  130. * sorts by `created` date descending, and **then** `lastName`
  131. *
  132. * @example
  133. * import * as D from 'fp-ts/Date'
  134. * import { pipe } from 'fp-ts/function'
  135. * import { contramap, getSemigroup, Ord, reverse } from 'fp-ts/Ord'
  136. * import * as RA from 'fp-ts/ReadonlyArray'
  137. * import * as S from 'fp-ts/string'
  138. *
  139. * interface User {
  140. * readonly id: string
  141. * readonly lastName: string
  142. * readonly created: Date
  143. * }
  144. *
  145. * const ordByLastName: Ord<User> = pipe(
  146. * S.Ord,
  147. * contramap((user) => user.lastName)
  148. * )
  149. *
  150. * const ordByCreated: Ord<User> = pipe(
  151. * D.Ord,
  152. * contramap((user) => user.created)
  153. * )
  154. *
  155. * const ordUserByCreatedDescThenLastName = getSemigroup<User>().concat(
  156. * reverse(ordByCreated),
  157. * ordByLastName
  158. * )
  159. *
  160. * assert.deepStrictEqual(
  161. * RA.sort(ordUserByCreatedDescThenLastName)([
  162. * { id: 'c', lastName: 'd', created: new Date(1973, 10, 30) },
  163. * { id: 'a', lastName: 'b', created: new Date(1973, 10, 30) },
  164. * { id: 'e', lastName: 'f', created: new Date(1980, 10, 30) }
  165. * ]),
  166. * [
  167. * { id: 'e', lastName: 'f', created: new Date(1980, 10, 30) },
  168. * { id: 'a', lastName: 'b', created: new Date(1973, 10, 30) },
  169. * { id: 'c', lastName: 'd', created: new Date(1973, 10, 30) }
  170. * ]
  171. * )
  172. *
  173. * @category instances
  174. * @since 2.0.0
  175. */
  176. var getSemigroup = function () { return ({
  177. concat: function (first, second) {
  178. return (0, exports.fromCompare)(function (a, b) {
  179. var ox = first.compare(a, b);
  180. return ox !== 0 ? ox : second.compare(a, b);
  181. });
  182. }
  183. }); };
  184. exports.getSemigroup = getSemigroup;
  185. /**
  186. * Returns a `Monoid` such that:
  187. *
  188. * - its `concat(ord1, ord2)` operation will order first by `ord1`, and then by `ord2`
  189. * - its `empty` value is an `Ord` that always considers compared elements equal
  190. *
  191. * @example
  192. * import { sort } from 'fp-ts/Array'
  193. * import { contramap, reverse, getMonoid } from 'fp-ts/Ord'
  194. * import * as S from 'fp-ts/string'
  195. * import * as B from 'fp-ts/boolean'
  196. * import { pipe } from 'fp-ts/function'
  197. * import { concatAll } from 'fp-ts/Monoid'
  198. * import * as N from 'fp-ts/number'
  199. *
  200. * interface User {
  201. * readonly id: number
  202. * readonly name: string
  203. * readonly age: number
  204. * readonly rememberMe: boolean
  205. * }
  206. *
  207. * const byName = pipe(
  208. * S.Ord,
  209. * contramap((p: User) => p.name)
  210. * )
  211. *
  212. * const byAge = pipe(
  213. * N.Ord,
  214. * contramap((p: User) => p.age)
  215. * )
  216. *
  217. * const byRememberMe = pipe(
  218. * B.Ord,
  219. * contramap((p: User) => p.rememberMe)
  220. * )
  221. *
  222. * const M = getMonoid<User>()
  223. *
  224. * const users: Array<User> = [
  225. * { id: 1, name: 'Guido', age: 47, rememberMe: false },
  226. * { id: 2, name: 'Guido', age: 46, rememberMe: true },
  227. * { id: 3, name: 'Giulio', age: 44, rememberMe: false },
  228. * { id: 4, name: 'Giulio', age: 44, rememberMe: true }
  229. * ]
  230. *
  231. * // sort by name, then by age, then by `rememberMe`
  232. * const O1 = concatAll(M)([byName, byAge, byRememberMe])
  233. * assert.deepStrictEqual(sort(O1)(users), [
  234. * { id: 3, name: 'Giulio', age: 44, rememberMe: false },
  235. * { id: 4, name: 'Giulio', age: 44, rememberMe: true },
  236. * { id: 2, name: 'Guido', age: 46, rememberMe: true },
  237. * { id: 1, name: 'Guido', age: 47, rememberMe: false }
  238. * ])
  239. *
  240. * // now `rememberMe = true` first, then by name, then by age
  241. * const O2 = concatAll(M)([reverse(byRememberMe), byName, byAge])
  242. * assert.deepStrictEqual(sort(O2)(users), [
  243. * { id: 4, name: 'Giulio', age: 44, rememberMe: true },
  244. * { id: 2, name: 'Guido', age: 46, rememberMe: true },
  245. * { id: 3, name: 'Giulio', age: 44, rememberMe: false },
  246. * { id: 1, name: 'Guido', age: 47, rememberMe: false }
  247. * ])
  248. *
  249. * @category instances
  250. * @since 2.4.0
  251. */
  252. var getMonoid = function () { return ({
  253. concat: (0, exports.getSemigroup)().concat,
  254. empty: (0, exports.fromCompare)(function () { return 0; })
  255. }); };
  256. exports.getMonoid = getMonoid;
  257. /**
  258. * @category instances
  259. * @since 2.7.0
  260. */
  261. exports.Contravariant = {
  262. URI: exports.URI,
  263. contramap: contramap_
  264. };
  265. // -------------------------------------------------------------------------------------
  266. // utils
  267. // -------------------------------------------------------------------------------------
  268. /**
  269. * @since 2.11.0
  270. */
  271. exports.trivial = {
  272. equals: function_1.constTrue,
  273. compare: /*#__PURE__*/ (0, function_1.constant)(0)
  274. };
  275. /**
  276. * @since 2.11.0
  277. */
  278. var equals = function (O) {
  279. return function (second) {
  280. return function (first) {
  281. return first === second || O.compare(first, second) === 0;
  282. };
  283. };
  284. };
  285. exports.equals = equals;
  286. // TODO: curry in v3
  287. /**
  288. * Test whether one value is _strictly less than_ another
  289. *
  290. * @since 2.0.0
  291. */
  292. var lt = function (O) {
  293. return function (first, second) {
  294. return O.compare(first, second) === -1;
  295. };
  296. };
  297. exports.lt = lt;
  298. // TODO: curry in v3
  299. /**
  300. * Test whether one value is _strictly greater than_ another
  301. *
  302. * @since 2.0.0
  303. */
  304. var gt = function (O) {
  305. return function (first, second) {
  306. return O.compare(first, second) === 1;
  307. };
  308. };
  309. exports.gt = gt;
  310. // TODO: curry in v3
  311. /**
  312. * Test whether one value is _non-strictly less than_ another
  313. *
  314. * @since 2.0.0
  315. */
  316. var leq = function (O) {
  317. return function (first, second) {
  318. return O.compare(first, second) !== 1;
  319. };
  320. };
  321. exports.leq = leq;
  322. // TODO: curry in v3
  323. /**
  324. * Test whether one value is _non-strictly greater than_ another
  325. *
  326. * @since 2.0.0
  327. */
  328. var geq = function (O) {
  329. return function (first, second) {
  330. return O.compare(first, second) !== -1;
  331. };
  332. };
  333. exports.geq = geq;
  334. // TODO: curry in v3
  335. /**
  336. * Take the minimum of two values. If they are considered equal, the first argument is chosen
  337. *
  338. * @since 2.0.0
  339. */
  340. var min = function (O) {
  341. return function (first, second) {
  342. return first === second || O.compare(first, second) < 1 ? first : second;
  343. };
  344. };
  345. exports.min = min;
  346. // TODO: curry in v3
  347. /**
  348. * Take the maximum of two values. If they are considered equal, the first argument is chosen
  349. *
  350. * @since 2.0.0
  351. */
  352. var max = function (O) {
  353. return function (first, second) {
  354. return first === second || O.compare(first, second) > -1 ? first : second;
  355. };
  356. };
  357. exports.max = max;
  358. /**
  359. * Clamp a value between a minimum and a maximum
  360. *
  361. * @since 2.0.0
  362. */
  363. var clamp = function (O) {
  364. var minO = (0, exports.min)(O);
  365. var maxO = (0, exports.max)(O);
  366. return function (low, hi) { return function (a) { return maxO(minO(a, hi), low); }; };
  367. };
  368. exports.clamp = clamp;
  369. /**
  370. * Test whether a value is between a minimum and a maximum (inclusive)
  371. *
  372. * @since 2.0.0
  373. */
  374. var between = function (O) {
  375. var ltO = (0, exports.lt)(O);
  376. var gtO = (0, exports.gt)(O);
  377. return function (low, hi) { return function (a) { return ltO(a, low) || gtO(a, hi) ? false : true; }; };
  378. };
  379. exports.between = between;
  380. // -------------------------------------------------------------------------------------
  381. // deprecated
  382. // -------------------------------------------------------------------------------------
  383. /**
  384. * Use [`tuple`](#tuple) instead.
  385. *
  386. * @category zone of death
  387. * @since 2.0.0
  388. * @deprecated
  389. */
  390. exports.getTupleOrd = exports.tuple;
  391. /**
  392. * Use [`reverse`](#reverse) instead.
  393. *
  394. * @category zone of death
  395. * @since 2.0.0
  396. * @deprecated
  397. */
  398. exports.getDualOrd = exports.reverse;
  399. /**
  400. * Use [`Contravariant`](#contravariant) instead.
  401. *
  402. * @category zone of death
  403. * @since 2.0.0
  404. * @deprecated
  405. */
  406. exports.ord = exports.Contravariant;
  407. // default compare for primitive types
  408. function compare(first, second) {
  409. return first < second ? -1 : first > second ? 1 : 0;
  410. }
  411. var strictOrd = {
  412. equals: Eq_1.eqStrict.equals,
  413. compare: compare
  414. };
  415. /**
  416. * Use [`Ord`](./boolean.ts.html#ord) instead.
  417. *
  418. * @category zone of death
  419. * @since 2.0.0
  420. * @deprecated
  421. */
  422. exports.ordBoolean = strictOrd;
  423. /**
  424. * Use [`Ord`](./string.ts.html#ord) instead.
  425. *
  426. * @category zone of death
  427. * @since 2.0.0
  428. * @deprecated
  429. */
  430. exports.ordString = strictOrd;
  431. /**
  432. * Use [`Ord`](./number.ts.html#ord) instead.
  433. *
  434. * @category zone of death
  435. * @since 2.0.0
  436. * @deprecated
  437. */
  438. exports.ordNumber = strictOrd;
  439. /**
  440. * Use [`Ord`](./Date.ts.html#ord) instead.
  441. *
  442. * @category zone of death
  443. * @since 2.0.0
  444. * @deprecated
  445. */
  446. exports.ordDate = (0, function_1.pipe)(exports.ordNumber,
  447. /*#__PURE__*/
  448. (0, exports.contramap)(function (date) { return date.valueOf(); }));