版博士V2.0程序
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 

523 строки
13 KiB

  1. /**
  2. * ```ts
  3. * interface Task<A> {
  4. * (): Promise<A>
  5. * }
  6. * ```
  7. *
  8. * `Task<A>` represents an asynchronous computation that yields a value of type `A` and **never fails**.
  9. * If you want to represent an asynchronous computation that may fail, please see `TaskEither`.
  10. *
  11. * @since 2.0.0
  12. */
  13. import { getApplicativeMonoid } from './Applicative';
  14. import { apFirst as apFirst_, apS as apS_, apSecond as apSecond_, getApplySemigroup as getApplySemigroup_ } from './Apply';
  15. import { bind as bind_, chainFirst as chainFirst_ } from './Chain';
  16. import { chainFirstIOK as chainFirstIOK_, chainIOK as chainIOK_, fromIOK as fromIOK_ } from './FromIO';
  17. import { identity, pipe } from './function';
  18. import { let as let__, bindTo as bindTo_, flap as flap_ } from './Functor';
  19. import * as _ from './internal';
  20. // -------------------------------------------------------------------------------------
  21. // conversions
  22. // -------------------------------------------------------------------------------------
  23. /**
  24. * @category conversions
  25. * @since 2.0.0
  26. */
  27. export var fromIO = function (ma) { return function () { return Promise.resolve().then(ma); }; };
  28. // -------------------------------------------------------------------------------------
  29. // combinators
  30. // -------------------------------------------------------------------------------------
  31. /**
  32. * Creates a task that will complete after a time delay
  33. *
  34. * @example
  35. * import { sequenceT } from 'fp-ts/Apply'
  36. * import * as T from 'fp-ts/Task'
  37. * import { takeRight } from 'fp-ts/Array'
  38. *
  39. * async function test() {
  40. * const log: Array<string> = []
  41. * const append = (message: string): T.Task<void> =>
  42. * T.fromIO(() => {
  43. * log.push(message)
  44. * })
  45. * const fa = append('a')
  46. * const fb = T.delay(20)(append('b'))
  47. * const fc = T.delay(10)(append('c'))
  48. * const fd = append('d')
  49. * await sequenceT(T.ApplyPar)(fa, fb, fc, fd)()
  50. * assert.deepStrictEqual(takeRight(2)(log), ['c', 'b'])
  51. * }
  52. *
  53. * test()
  54. *
  55. * @since 2.0.0
  56. */
  57. export function delay(millis) {
  58. return function (ma) { return function () {
  59. return new Promise(function (resolve) {
  60. setTimeout(function () {
  61. Promise.resolve().then(ma).then(resolve);
  62. }, millis);
  63. });
  64. }; };
  65. }
  66. var _map = function (fa, f) { return pipe(fa, map(f)); };
  67. var _apPar = function (fab, fa) { return pipe(fab, ap(fa)); };
  68. var _apSeq = function (fab, fa) {
  69. return pipe(fab, chain(function (f) { return pipe(fa, map(f)); }));
  70. };
  71. var _chain = function (ma, f) { return pipe(ma, chain(f)); };
  72. /**
  73. * `map` can be used to turn functions `(a: A) => B` into functions `(fa: F<A>) => F<B>` whose argument and return types
  74. * use the type constructor `F` to represent some computational context.
  75. *
  76. * @category mapping
  77. * @since 2.0.0
  78. */
  79. export var map = function (f) { return function (fa) { return function () {
  80. return Promise.resolve().then(fa).then(f);
  81. }; }; };
  82. /**
  83. * @since 2.0.0
  84. */
  85. export var ap = function (fa) { return function (fab) { return function () {
  86. return Promise.all([Promise.resolve().then(fab), Promise.resolve().then(fa)]).then(function (_a) {
  87. var f = _a[0], a = _a[1];
  88. return f(a);
  89. });
  90. }; }; };
  91. /**
  92. * @category constructors
  93. * @since 2.0.0
  94. */
  95. export var of = function (a) { return function () { return Promise.resolve(a); }; };
  96. /**
  97. * Composes computations in sequence, using the return value of one computation to determine the next computation.
  98. *
  99. * @category sequencing
  100. * @since 2.0.0
  101. */
  102. export var chain = function (f) { return function (ma) { return function () {
  103. return Promise.resolve()
  104. .then(ma)
  105. .then(function (a) { return f(a)(); });
  106. }; }; };
  107. /**
  108. * @category sequencing
  109. * @since 2.0.0
  110. */
  111. export var flatten = /*#__PURE__*/ chain(identity);
  112. /**
  113. * @category type lambdas
  114. * @since 2.0.0
  115. */
  116. export var URI = 'Task';
  117. /**
  118. * Monoid returning the first completed task.
  119. *
  120. * Note: uses `Promise.race` internally.
  121. *
  122. * @example
  123. * import * as T from 'fp-ts/Task'
  124. *
  125. * async function test() {
  126. * const S = T.getRaceMonoid<string>()
  127. * const fa = T.delay(20)(T.of('a'))
  128. * const fb = T.delay(10)(T.of('b'))
  129. * assert.deepStrictEqual(await S.concat(fa, fb)(), 'b')
  130. * }
  131. *
  132. * test()
  133. *
  134. * @category instances
  135. * @since 2.0.0
  136. */
  137. export function getRaceMonoid() {
  138. return {
  139. concat: function (x, y) { return function () { return Promise.race([Promise.resolve().then(x), Promise.resolve().then(y)]); }; },
  140. empty: never
  141. };
  142. }
  143. /**
  144. * @category instances
  145. * @since 2.7.0
  146. */
  147. export var Functor = {
  148. URI: URI,
  149. map: _map
  150. };
  151. /**
  152. * @category mapping
  153. * @since 2.10.0
  154. */
  155. export var flap = /*#__PURE__*/ flap_(Functor);
  156. /**
  157. * @category instances
  158. * @since 2.10.0
  159. */
  160. export var Pointed = {
  161. URI: URI,
  162. of: of
  163. };
  164. /**
  165. * Runs computations in parallel.
  166. *
  167. * @category instances
  168. * @since 2.10.0
  169. */
  170. export var ApplyPar = {
  171. URI: URI,
  172. map: _map,
  173. ap: _apPar
  174. };
  175. /**
  176. * Combine two effectful actions, keeping only the result of the first.
  177. *
  178. * @since 2.0.0
  179. */
  180. export var apFirst = /*#__PURE__*/ apFirst_(ApplyPar);
  181. /**
  182. * Combine two effectful actions, keeping only the result of the second.
  183. *
  184. * @since 2.0.0
  185. */
  186. export var apSecond = /*#__PURE__*/ apSecond_(ApplyPar);
  187. /**
  188. * Runs computations in parallel.
  189. *
  190. * @category instances
  191. * @since 2.7.0
  192. */
  193. export var ApplicativePar = {
  194. URI: URI,
  195. map: _map,
  196. ap: _apPar,
  197. of: of
  198. };
  199. /**
  200. * Runs computations sequentially.
  201. *
  202. * @category instances
  203. * @since 2.10.0
  204. */
  205. export var ApplySeq = {
  206. URI: URI,
  207. map: _map,
  208. ap: _apSeq
  209. };
  210. /**
  211. * Runs computations sequentially.
  212. *
  213. * @category instances
  214. * @since 2.7.0
  215. */
  216. export var ApplicativeSeq = {
  217. URI: URI,
  218. map: _map,
  219. ap: _apSeq,
  220. of: of
  221. };
  222. /**
  223. * @category instances
  224. * @since 2.10.0
  225. */
  226. export var Chain = {
  227. URI: URI,
  228. map: _map,
  229. ap: _apPar,
  230. chain: _chain
  231. };
  232. /**
  233. * @category instances
  234. * @since 2.10.0
  235. */
  236. export var Monad = {
  237. URI: URI,
  238. map: _map,
  239. of: of,
  240. ap: _apPar,
  241. chain: _chain
  242. };
  243. /**
  244. * @category instances
  245. * @since 2.10.0
  246. */
  247. export var MonadIO = {
  248. URI: URI,
  249. map: _map,
  250. of: of,
  251. ap: _apPar,
  252. chain: _chain,
  253. fromIO: fromIO
  254. };
  255. /**
  256. * @category zone of death
  257. * @since 2.7.0
  258. * @deprecated
  259. */
  260. export var fromTask = identity;
  261. /**
  262. * @category instances
  263. * @since 2.10.0
  264. */
  265. export var MonadTask = {
  266. URI: URI,
  267. map: _map,
  268. of: of,
  269. ap: _apPar,
  270. chain: _chain,
  271. fromIO: fromIO,
  272. fromTask: fromTask
  273. };
  274. /**
  275. * Composes computations in sequence, using the return value of one computation to determine the next computation and
  276. * keeping only the result of the first.
  277. *
  278. * @category sequencing
  279. * @since 2.0.0
  280. */
  281. export var chainFirst = /*#__PURE__*/ chainFirst_(Chain);
  282. /**
  283. * @category instances
  284. * @since 2.10.0
  285. */
  286. export var FromIO = {
  287. URI: URI,
  288. fromIO: fromIO
  289. };
  290. /**
  291. * @category lifting
  292. * @since 2.4.0
  293. */
  294. export var fromIOK =
  295. /*#__PURE__*/ fromIOK_(FromIO);
  296. /**
  297. * @category sequencing
  298. * @since 2.4.0
  299. */
  300. export var chainIOK = /*#__PURE__*/ chainIOK_(FromIO, Chain);
  301. /**
  302. * @category sequencing
  303. * @since 2.10.0
  304. */
  305. export var chainFirstIOK = /*#__PURE__*/ chainFirstIOK_(FromIO, Chain);
  306. /**
  307. * @category instances
  308. * @since 2.10.0
  309. */
  310. export var FromTask = {
  311. URI: URI,
  312. fromIO: fromIO,
  313. fromTask: fromTask
  314. };
  315. // -------------------------------------------------------------------------------------
  316. // utils
  317. // -------------------------------------------------------------------------------------
  318. /**
  319. * A `Task` that never completes.
  320. *
  321. * @since 2.0.0
  322. */
  323. export var never = function () { return new Promise(function (_) { return undefined; }); };
  324. // -------------------------------------------------------------------------------------
  325. // do notation
  326. // -------------------------------------------------------------------------------------
  327. /**
  328. * @category do notation
  329. * @since 2.9.0
  330. */
  331. export var Do = /*#__PURE__*/ of(_.emptyRecord);
  332. /**
  333. * @category do notation
  334. * @since 2.8.0
  335. */
  336. export var bindTo = /*#__PURE__*/ bindTo_(Functor);
  337. var let_ = /*#__PURE__*/ let__(Functor);
  338. export {
  339. /**
  340. * @category do notation
  341. * @since 2.13.0
  342. */
  343. let_ as let };
  344. /**
  345. * @category do notation
  346. * @since 2.8.0
  347. */
  348. export var bind = /*#__PURE__*/ bind_(Chain);
  349. /**
  350. * @category do notation
  351. * @since 2.8.0
  352. */
  353. export var apS = /*#__PURE__*/ apS_(ApplyPar);
  354. /**
  355. * @since 2.11.0
  356. */
  357. export var ApT = /*#__PURE__*/ of(_.emptyReadonlyArray);
  358. // -------------------------------------------------------------------------------------
  359. // array utils
  360. // -------------------------------------------------------------------------------------
  361. /**
  362. * Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(ApplicativePar)`.
  363. *
  364. * @category traversing
  365. * @since 2.11.0
  366. */
  367. export var traverseReadonlyNonEmptyArrayWithIndex = function (f) {
  368. return function (as) {
  369. return function () {
  370. return Promise.all(as.map(function (a, i) { return Promise.resolve().then(function () { return f(i, a)(); }); }));
  371. };
  372. };
  373. };
  374. /**
  375. * Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativePar)`.
  376. *
  377. * @category traversing
  378. * @since 2.11.0
  379. */
  380. export var traverseReadonlyArrayWithIndex = function (f) {
  381. var g = traverseReadonlyNonEmptyArrayWithIndex(f);
  382. return function (as) { return (_.isNonEmpty(as) ? g(as) : ApT); };
  383. };
  384. /**
  385. * Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(ApplicativeSeq)`.
  386. *
  387. * @category traversing
  388. * @since 2.11.0
  389. */
  390. export var traverseReadonlyNonEmptyArrayWithIndexSeq = function (f) {
  391. return function (as) {
  392. return function () {
  393. return _.tail(as).reduce(function (acc, a, i) {
  394. return acc.then(function (bs) {
  395. return Promise.resolve()
  396. .then(f(i + 1, a))
  397. .then(function (b) {
  398. bs.push(b);
  399. return bs;
  400. });
  401. });
  402. }, Promise.resolve()
  403. .then(f(0, _.head(as)))
  404. .then(_.singleton));
  405. };
  406. };
  407. };
  408. /**
  409. * Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativeSeq)`.
  410. *
  411. * @category traversing
  412. * @since 2.11.0
  413. */
  414. export var traverseReadonlyArrayWithIndexSeq = function (f) {
  415. var g = traverseReadonlyNonEmptyArrayWithIndexSeq(f);
  416. return function (as) { return (_.isNonEmpty(as) ? g(as) : ApT); };
  417. };
  418. /**
  419. * Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`.
  420. *
  421. * @category traversing
  422. * @since 2.9.0
  423. */
  424. export var traverseArrayWithIndex = traverseReadonlyArrayWithIndex;
  425. /**
  426. * Equivalent to `ReadonlyArray#traverse(Applicative)`.
  427. *
  428. * @category traversing
  429. * @since 2.9.0
  430. */
  431. export var traverseArray = function (f) {
  432. return traverseReadonlyArrayWithIndex(function (_, a) { return f(a); });
  433. };
  434. /**
  435. * Equivalent to `ReadonlyArray#sequence(Applicative)`.
  436. *
  437. * @category traversing
  438. * @since 2.9.0
  439. */
  440. export var sequenceArray =
  441. /*#__PURE__*/ traverseArray(identity);
  442. /**
  443. * Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativeSeq)`.
  444. *
  445. * @category traversing
  446. * @since 2.9.0
  447. */
  448. export var traverseSeqArrayWithIndex = traverseReadonlyArrayWithIndexSeq;
  449. /**
  450. * Equivalent to `ReadonlyArray#traverse(ApplicativeSeq)`.
  451. *
  452. * @category traversing
  453. * @since 2.9.0
  454. */
  455. export var traverseSeqArray = function (f) {
  456. return traverseReadonlyArrayWithIndexSeq(function (_, a) { return f(a); });
  457. };
  458. /**
  459. * Equivalent to `ReadonlyArray#sequence(ApplicativeSeq)`.
  460. *
  461. * @category traversing
  462. * @since 2.9.0
  463. */
  464. export var sequenceSeqArray =
  465. /*#__PURE__*/ traverseSeqArray(identity);
  466. // -------------------------------------------------------------------------------------
  467. // deprecated
  468. // -------------------------------------------------------------------------------------
  469. /**
  470. * This instance is deprecated, use small, specific instances instead.
  471. * For example if a function needs a `Functor` instance, pass `T.Functor` instead of `T.task`
  472. * (where `T` is from `import T from 'fp-ts/Task'`)
  473. *
  474. * @category zone of death
  475. * @since 2.0.0
  476. * @deprecated
  477. */
  478. export var task = {
  479. URI: URI,
  480. map: _map,
  481. of: of,
  482. ap: _apPar,
  483. chain: _chain,
  484. fromIO: fromIO,
  485. fromTask: fromTask
  486. };
  487. /**
  488. * This instance is deprecated, use small, specific instances instead.
  489. * For example if a function needs a `Functor` instance, pass `T.Functor` instead of `T.taskSeq`
  490. * (where `T` is from `import T from 'fp-ts/Task'`)
  491. *
  492. * @category zone of death
  493. * @since 2.0.0
  494. * @deprecated
  495. */
  496. export var taskSeq = {
  497. URI: URI,
  498. map: _map,
  499. of: of,
  500. ap: _apSeq,
  501. chain: _chain,
  502. fromIO: fromIO,
  503. fromTask: fromTask
  504. };
  505. /**
  506. * Use [`getApplySemigroup`](./Apply.ts.html#getapplysemigroup) instead.
  507. *
  508. * @category zone of death
  509. * @since 2.0.0
  510. * @deprecated
  511. */
  512. export var getSemigroup = /*#__PURE__*/ getApplySemigroup_(ApplySeq);
  513. /**
  514. * Use [`getApplicativeMonoid`](./Applicative.ts.html#getapplicativemonoid) instead.
  515. *
  516. * Lift a monoid into 'Task', the inner values are concatenated using the provided `Monoid`.
  517. *
  518. * @category zone of death
  519. * @since 2.0.0
  520. * @deprecated
  521. */
  522. export var getMonoid = /*#__PURE__*/ getApplicativeMonoid(ApplicativeSeq);