版博士V2.0程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

481 lines
12 KiB

  1. import { apFirst as apFirst_, apS as apS_, apSecond as apSecond_ } from './Apply';
  2. import * as A from './Array';
  3. import { bind as bind_, chainFirst as chainFirst_ } from './Chain';
  4. import { fromEquals } from './Eq';
  5. import { identity, pipe } from './function';
  6. import { let as let__, bindTo as bindTo_, flap as flap_ } from './Functor';
  7. import * as _ from './internal';
  8. /**
  9. * @category constructors
  10. * @since 2.0.0
  11. */
  12. export function make(value, forest) {
  13. if (forest === void 0) { forest = []; }
  14. return {
  15. value: value,
  16. forest: forest
  17. };
  18. }
  19. /**
  20. * @category instances
  21. * @since 2.0.0
  22. */
  23. export function getShow(S) {
  24. var show = function (t) {
  25. return A.isEmpty(t.forest)
  26. ? "make(".concat(S.show(t.value), ")")
  27. : "make(".concat(S.show(t.value), ", [").concat(t.forest.map(show).join(', '), "])");
  28. };
  29. return {
  30. show: show
  31. };
  32. }
  33. /**
  34. * @category instances
  35. * @since 2.0.0
  36. */
  37. export function getEq(E) {
  38. // eslint-disable-next-line prefer-const
  39. var SA;
  40. var R = fromEquals(function (x, y) { return E.equals(x.value, y.value) && SA.equals(x.forest, y.forest); });
  41. SA = A.getEq(R);
  42. return R;
  43. }
  44. var draw = function (indentation, forest) {
  45. var r = '';
  46. var len = forest.length;
  47. var tree;
  48. for (var i = 0; i < len; i++) {
  49. tree = forest[i];
  50. var isLast = i === len - 1;
  51. r += indentation + (isLast ? '└' : '├') + '─ ' + tree.value;
  52. r += draw(indentation + (len > 1 && !isLast ? '│ ' : ' '), tree.forest);
  53. }
  54. return r;
  55. };
  56. /**
  57. * Neat 2-dimensional drawing of a forest
  58. *
  59. * @since 2.0.0
  60. */
  61. export function drawForest(forest) {
  62. return draw('\n', forest);
  63. }
  64. /**
  65. * Neat 2-dimensional drawing of a tree
  66. *
  67. * @example
  68. * import { make, drawTree } from 'fp-ts/Tree'
  69. *
  70. * const fa = make('a', [
  71. * make('b'),
  72. * make('c'),
  73. * make('d', [make('e'), make('f')])
  74. * ])
  75. *
  76. * assert.strictEqual(drawTree(fa), `a
  77. * ├─ b
  78. * ├─ c
  79. * └─ d
  80. * ├─ e
  81. * └─ f`)
  82. *
  83. *
  84. * @since 2.0.0
  85. */
  86. export function drawTree(tree) {
  87. return tree.value + drawForest(tree.forest);
  88. }
  89. /**
  90. * Build a (possibly infinite) tree from a seed value in breadth-first order.
  91. *
  92. * @category constructors
  93. * @since 2.0.0
  94. */
  95. export function unfoldTree(b, f) {
  96. var _a = f(b), a = _a[0], bs = _a[1];
  97. return { value: a, forest: unfoldForest(bs, f) };
  98. }
  99. /**
  100. * Build a (possibly infinite) forest from a list of seed values in breadth-first order.
  101. *
  102. * @category constructors
  103. * @since 2.0.0
  104. */
  105. export function unfoldForest(bs, f) {
  106. return bs.map(function (b) { return unfoldTree(b, f); });
  107. }
  108. export function unfoldTreeM(M) {
  109. var unfoldForestMM = unfoldForestM(M);
  110. return function (b, f) { return M.chain(f(b), function (_a) {
  111. var a = _a[0], bs = _a[1];
  112. return M.map(unfoldForestMM(bs, f), function (ts) { return ({ value: a, forest: ts }); });
  113. }); };
  114. }
  115. export function unfoldForestM(M) {
  116. var traverseM = A.traverse(M);
  117. return function (bs, f) {
  118. return pipe(bs, traverseM(function (b) { return unfoldTreeM(M)(b, f); }));
  119. };
  120. }
  121. /**
  122. * Fold a tree into a "summary" value in depth-first order.
  123. *
  124. * For each node in the tree, apply `f` to the `value` and the result of applying `f` to each `forest`.
  125. *
  126. * This is also known as the catamorphism on trees.
  127. *
  128. * @example
  129. * import { fold, make } from 'fp-ts/Tree'
  130. * import { concatAll } from 'fp-ts/Monoid'
  131. * import { MonoidSum } from 'fp-ts/number'
  132. *
  133. * const t = make(1, [make(2), make(3)])
  134. *
  135. * const sum = concatAll(MonoidSum)
  136. *
  137. * // Sum the values in a tree:
  138. * assert.deepStrictEqual(fold((a: number, bs: Array<number>) => a + sum(bs))(t), 6)
  139. *
  140. * // Find the maximum value in the tree:
  141. * assert.deepStrictEqual(fold((a: number, bs: Array<number>) => bs.reduce((b, acc) => Math.max(b, acc), a))(t), 3)
  142. *
  143. * // Count the number of leaves in the tree:
  144. * assert.deepStrictEqual(fold((_: number, bs: Array<number>) => (bs.length === 0 ? 1 : sum(bs)))(t), 2)
  145. *
  146. * @category folding
  147. * @since 2.6.0
  148. */
  149. export function fold(f) {
  150. var go = function (tree) { return f(tree.value, tree.forest.map(go)); };
  151. return go;
  152. }
  153. /* istanbul ignore next */
  154. var _map = function (fa, f) { return pipe(fa, map(f)); };
  155. var _ap = function (fab, fa) {
  156. return pipe(fab, chain(function (f) { return pipe(fa, map(f)); }));
  157. };
  158. /* istanbul ignore next */
  159. var _chain = function (ma, f) { return pipe(ma, chain(f)); };
  160. /* istanbul ignore next */
  161. var _reduce = function (fa, b, f) { return pipe(fa, reduce(b, f)); };
  162. /* istanbul ignore next */
  163. var _foldMap = function (M) {
  164. var foldMapM = foldMap(M);
  165. return function (fa, f) { return pipe(fa, foldMapM(f)); };
  166. };
  167. /* istanbul ignore next */
  168. var _reduceRight = function (fa, b, f) { return pipe(fa, reduceRight(b, f)); };
  169. /* istanbul ignore next */
  170. var _extend = function (wa, f) { return pipe(wa, extend(f)); };
  171. /* istanbul ignore next */
  172. var _traverse = function (F) {
  173. var traverseF = traverse(F);
  174. return function (ta, f) { return pipe(ta, traverseF(f)); };
  175. };
  176. /**
  177. * @since 2.0.0
  178. */
  179. export var ap = function (fa) { return function (fab) { return _ap(fab, fa); }; };
  180. /**
  181. * Composes computations in sequence, using the return value of one computation to determine the next computation.
  182. *
  183. * @category Monad
  184. * @since 2.0.0
  185. */
  186. export var chain = function (f) {
  187. return function (ma) {
  188. var _a = f(ma.value), value = _a.value, forest = _a.forest;
  189. var concat = A.getMonoid().concat;
  190. return {
  191. value: value,
  192. forest: concat(forest, ma.forest.map(chain(f)))
  193. };
  194. };
  195. };
  196. /**
  197. * @since 2.0.0
  198. */
  199. export var extend = function (f) { return function (wa) { return ({
  200. value: f(wa),
  201. forest: wa.forest.map(extend(f))
  202. }); }; };
  203. /**
  204. * @since 2.0.0
  205. */
  206. export var duplicate = /*#__PURE__*/ extend(identity);
  207. /**
  208. * @category sequencing
  209. * @since 2.0.0
  210. */
  211. export var flatten = /*#__PURE__*/ chain(identity);
  212. /**
  213. * `map` can be used to turn functions `(a: A) => B` into functions `(fa: F<A>) => F<B>` whose argument and return types
  214. * use the type constructor `F` to represent some computational context.
  215. *
  216. * @category mapping
  217. * @since 2.0.0
  218. */
  219. export var map = function (f) { return function (fa) { return ({
  220. value: f(fa.value),
  221. forest: fa.forest.map(map(f))
  222. }); }; };
  223. /**
  224. * @category folding
  225. * @since 2.0.0
  226. */
  227. export var reduce = function (b, f) {
  228. return function (fa) {
  229. var r = f(b, fa.value);
  230. var len = fa.forest.length;
  231. for (var i = 0; i < len; i++) {
  232. r = pipe(fa.forest[i], reduce(r, f));
  233. }
  234. return r;
  235. };
  236. };
  237. /**
  238. * @category folding
  239. * @since 2.0.0
  240. */
  241. export var foldMap = function (M) { return function (f) {
  242. return reduce(M.empty, function (acc, a) { return M.concat(acc, f(a)); });
  243. }; };
  244. /**
  245. * @category folding
  246. * @since 2.0.0
  247. */
  248. export var reduceRight = function (b, f) {
  249. return function (fa) {
  250. var r = b;
  251. var len = fa.forest.length;
  252. for (var i = len - 1; i >= 0; i--) {
  253. r = pipe(fa.forest[i], reduceRight(r, f));
  254. }
  255. return f(fa.value, r);
  256. };
  257. };
  258. /**
  259. * @category Extract
  260. * @since 2.6.2
  261. */
  262. export var extract = function (wa) { return wa.value; };
  263. /**
  264. * @category traversing
  265. * @since 2.6.3
  266. */
  267. export var traverse = function (F) {
  268. var traverseF = A.traverse(F);
  269. var out = function (f) {
  270. return function (ta) {
  271. return F.ap(F.map(f(ta.value), function (value) { return function (forest) { return ({
  272. value: value,
  273. forest: forest
  274. }); }; }), pipe(ta.forest, traverseF(out(f))));
  275. };
  276. };
  277. return out;
  278. };
  279. /**
  280. * @category traversing
  281. * @since 2.6.3
  282. */
  283. export var sequence = function (F) { return traverse(F)(identity); };
  284. /**
  285. * @category constructors
  286. * @since 2.7.0
  287. */
  288. export var of = function (a) { return make(a); };
  289. /**
  290. * @category type lambdas
  291. * @since 2.0.0
  292. */
  293. export var URI = 'Tree';
  294. /**
  295. * @category instances
  296. * @since 2.7.0
  297. */
  298. export var Functor = {
  299. URI: URI,
  300. map: _map
  301. };
  302. /**
  303. * @category mapping
  304. * @since 2.10.0
  305. */
  306. export var flap = /*#__PURE__*/ flap_(Functor);
  307. /**
  308. * @category instances
  309. * @since 2.10.0
  310. */
  311. export var Pointed = {
  312. URI: URI,
  313. of: of
  314. };
  315. /**
  316. * @category instances
  317. * @since 2.10.0
  318. */
  319. export var Apply = {
  320. URI: URI,
  321. map: _map,
  322. ap: _ap
  323. };
  324. /**
  325. * Combine two effectful actions, keeping only the result of the first.
  326. *
  327. * @since 2.0.0
  328. */
  329. export var apFirst = /*#__PURE__*/ apFirst_(Apply);
  330. /**
  331. * Combine two effectful actions, keeping only the result of the second.
  332. *
  333. * @since 2.0.0
  334. */
  335. export var apSecond = /*#__PURE__*/ apSecond_(Apply);
  336. /**
  337. * @category instances
  338. * @since 2.7.0
  339. */
  340. export var Applicative = {
  341. URI: URI,
  342. map: _map,
  343. ap: _ap,
  344. of: of
  345. };
  346. /**
  347. * @category instances
  348. * @since 2.10.0
  349. */
  350. export var Chain = {
  351. URI: URI,
  352. map: _map,
  353. ap: _ap,
  354. chain: _chain
  355. };
  356. /**
  357. * @category instances
  358. * @since 2.7.0
  359. */
  360. export var Monad = {
  361. URI: URI,
  362. map: _map,
  363. ap: _ap,
  364. of: of,
  365. chain: _chain
  366. };
  367. /**
  368. * Composes computations in sequence, using the return value of one computation to determine the next computation and
  369. * keeping only the result of the first.
  370. *
  371. * @since 2.0.0
  372. */
  373. export var chainFirst = /*#__PURE__*/ chainFirst_(Chain);
  374. /**
  375. * @category instances
  376. * @since 2.7.0
  377. */
  378. export var Foldable = {
  379. URI: URI,
  380. reduce: _reduce,
  381. foldMap: _foldMap,
  382. reduceRight: _reduceRight
  383. };
  384. /**
  385. * @category instances
  386. * @since 2.7.0
  387. */
  388. export var Traversable = {
  389. URI: URI,
  390. map: _map,
  391. reduce: _reduce,
  392. foldMap: _foldMap,
  393. reduceRight: _reduceRight,
  394. traverse: _traverse,
  395. sequence: sequence
  396. };
  397. /**
  398. * @category instances
  399. * @since 2.7.0
  400. */
  401. export var Comonad = {
  402. URI: URI,
  403. map: _map,
  404. extend: _extend,
  405. extract: extract
  406. };
  407. // -------------------------------------------------------------------------------------
  408. // do notation
  409. // -------------------------------------------------------------------------------------
  410. /**
  411. * @category do notation
  412. * @since 2.9.0
  413. */
  414. export var Do = /*#__PURE__*/ of(_.emptyRecord);
  415. /**
  416. * @category do notation
  417. * @since 2.8.0
  418. */
  419. export var bindTo = /*#__PURE__*/ bindTo_(Functor);
  420. var let_ = /*#__PURE__*/ let__(Functor);
  421. export {
  422. /**
  423. * @category do notation
  424. * @since 2.13.0
  425. */
  426. let_ as let };
  427. /**
  428. * @category do notation
  429. * @since 2.8.0
  430. */
  431. export var bind = /*#__PURE__*/ bind_(Chain);
  432. /**
  433. * @category do notation
  434. * @since 2.8.0
  435. */
  436. export var apS = /*#__PURE__*/ apS_(Apply);
  437. // -------------------------------------------------------------------------------------
  438. // utils
  439. // -------------------------------------------------------------------------------------
  440. /**
  441. * @since 2.0.0
  442. */
  443. export function elem(E) {
  444. var go = function (a, fa) { return E.equals(a, fa.value) || fa.forest.some(function (tree) { return go(a, tree); }); };
  445. return go;
  446. }
  447. /**
  448. * @since 2.11.0
  449. */
  450. export var exists = function (predicate) {
  451. return function (ma) {
  452. return predicate(ma.value) || ma.forest.some(exists(predicate));
  453. };
  454. };
  455. // -------------------------------------------------------------------------------------
  456. // deprecated
  457. // -------------------------------------------------------------------------------------
  458. /**
  459. * This instance is deprecated, use small, specific instances instead.
  460. * For example if a function needs a `Functor` instance, pass `T.Functor` instead of `T.tree`
  461. * (where `T` is from `import T from 'fp-ts/Tree'`)
  462. *
  463. * @category zone of death
  464. * @since 2.0.0
  465. * @deprecated
  466. */
  467. export var tree = {
  468. URI: URI,
  469. map: _map,
  470. of: of,
  471. ap: _ap,
  472. chain: _chain,
  473. reduce: _reduce,
  474. foldMap: _foldMap,
  475. reduceRight: _reduceRight,
  476. traverse: _traverse,
  477. sequence: sequence,
  478. extract: extract,
  479. extend: _extend
  480. };