@clayroach/effect 3.19.14-source-capture.8 → 3.19.14-source-trace.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (452) hide show
  1. package/SourceLocation/package.json +6 -0
  2. package/dist/cjs/Effect.js +2 -28
  3. package/dist/cjs/Effect.js.map +1 -1
  4. package/dist/cjs/FiberRef.js +12 -1
  5. package/dist/cjs/FiberRef.js.map +1 -1
  6. package/dist/cjs/Layer.js +2 -24
  7. package/dist/cjs/Layer.js.map +1 -1
  8. package/dist/cjs/RuntimeFlags.js +1 -29
  9. package/dist/cjs/RuntimeFlags.js.map +1 -1
  10. package/dist/cjs/SourceLocation.js +60 -0
  11. package/dist/cjs/SourceLocation.js.map +1 -0
  12. package/dist/cjs/Tracer.js +1 -15
  13. package/dist/cjs/Tracer.js.map +1 -1
  14. package/dist/cjs/Utils.js +1 -1
  15. package/dist/cjs/Utils.js.map +1 -1
  16. package/dist/cjs/index.js +3 -1
  17. package/dist/cjs/index.js.map +1 -1
  18. package/dist/cjs/internal/clock.js +1 -1
  19. package/dist/cjs/internal/clock.js.map +1 -1
  20. package/dist/cjs/internal/core.js +17 -50
  21. package/dist/cjs/internal/core.js.map +1 -1
  22. package/dist/cjs/internal/effect/circular.js +18 -30
  23. package/dist/cjs/internal/effect/circular.js.map +1 -1
  24. package/dist/cjs/internal/fiberRuntime.js +16 -65
  25. package/dist/cjs/internal/fiberRuntime.js.map +1 -1
  26. package/dist/cjs/internal/layer/circular.js +1 -5
  27. package/dist/cjs/internal/layer/circular.js.map +1 -1
  28. package/dist/cjs/internal/layer.js +1 -3
  29. package/dist/cjs/internal/layer.js.map +1 -1
  30. package/dist/cjs/internal/logger.js +25 -2
  31. package/dist/cjs/internal/logger.js.map +1 -1
  32. package/dist/cjs/internal/runtimeFlags.js +2 -11
  33. package/dist/cjs/internal/runtimeFlags.js.map +1 -1
  34. package/dist/cjs/internal/tracer.js +1 -114
  35. package/dist/cjs/internal/tracer.js.map +1 -1
  36. package/dist/dts/Config.d.ts +2 -2
  37. package/dist/dts/Config.d.ts.map +1 -1
  38. package/dist/dts/Effect.d.ts +8 -29
  39. package/dist/dts/Effect.d.ts.map +1 -1
  40. package/dist/dts/FiberRef.d.ts +12 -0
  41. package/dist/dts/FiberRef.d.ts.map +1 -1
  42. package/dist/dts/Layer.d.ts +0 -22
  43. package/dist/dts/Layer.d.ts.map +1 -1
  44. package/dist/dts/RuntimeFlags.d.ts +0 -28
  45. package/dist/dts/RuntimeFlags.d.ts.map +1 -1
  46. package/dist/dts/SourceLocation.d.ts +88 -0
  47. package/dist/dts/SourceLocation.d.ts.map +1 -0
  48. package/dist/dts/Tracer.d.ts +0 -15
  49. package/dist/dts/Tracer.d.ts.map +1 -1
  50. package/dist/dts/index.d.ts +6 -0
  51. package/dist/dts/index.d.ts.map +1 -1
  52. package/dist/dts/internal/core.d.ts.map +1 -1
  53. package/dist/dts/internal/layer.d.ts.map +1 -1
  54. package/dist/dts/internal/runtimeFlags.d.ts.map +1 -1
  55. package/dist/esm/Effect.js +0 -26
  56. package/dist/esm/Effect.js.map +1 -1
  57. package/dist/esm/FiberRef.js +11 -0
  58. package/dist/esm/FiberRef.js.map +1 -1
  59. package/dist/esm/Layer.js +0 -22
  60. package/dist/esm/Layer.js.map +1 -1
  61. package/dist/esm/RuntimeFlags.js +0 -28
  62. package/dist/esm/RuntimeFlags.js.map +1 -1
  63. package/dist/esm/SourceLocation.js +51 -0
  64. package/dist/esm/SourceLocation.js.map +1 -0
  65. package/dist/esm/Tracer.js +0 -14
  66. package/dist/esm/Tracer.js.map +1 -1
  67. package/dist/esm/Utils.js +1 -1
  68. package/dist/esm/Utils.js.map +1 -1
  69. package/dist/esm/index.js +6 -0
  70. package/dist/esm/index.js.map +1 -1
  71. package/dist/esm/internal/clock.js +1 -1
  72. package/dist/esm/internal/clock.js.map +1 -1
  73. package/dist/esm/internal/core.js +12 -45
  74. package/dist/esm/internal/core.js.map +1 -1
  75. package/dist/esm/internal/effect/circular.js +18 -30
  76. package/dist/esm/internal/effect/circular.js.map +1 -1
  77. package/dist/esm/internal/fiberRuntime.js +13 -60
  78. package/dist/esm/internal/fiberRuntime.js.map +1 -1
  79. package/dist/esm/internal/layer/circular.js +0 -4
  80. package/dist/esm/internal/layer/circular.js.map +1 -1
  81. package/dist/esm/internal/layer.js +0 -2
  82. package/dist/esm/internal/layer.js.map +1 -1
  83. package/dist/esm/internal/logger.js +25 -2
  84. package/dist/esm/internal/logger.js.map +1 -1
  85. package/dist/esm/internal/runtimeFlags.js +1 -9
  86. package/dist/esm/internal/runtimeFlags.js.map +1 -1
  87. package/dist/esm/internal/tracer.js +0 -111
  88. package/dist/esm/internal/tracer.js.map +1 -1
  89. package/package.json +12 -1
  90. package/src/Arbitrary.ts +1101 -0
  91. package/src/Array.ts +3589 -0
  92. package/src/BigDecimal.ts +1349 -0
  93. package/src/BigInt.ts +643 -0
  94. package/src/Boolean.ts +287 -0
  95. package/src/Brand.ts +360 -0
  96. package/src/Cache.ts +281 -0
  97. package/src/Cause.ts +1555 -0
  98. package/src/Channel.ts +2355 -0
  99. package/src/ChildExecutorDecision.ts +146 -0
  100. package/src/Chunk.ts +1495 -0
  101. package/src/Clock.ts +111 -0
  102. package/src/Config.ts +542 -0
  103. package/src/ConfigError.ts +270 -0
  104. package/src/ConfigProvider.ts +333 -0
  105. package/src/ConfigProviderPathPatch.ts +100 -0
  106. package/src/Console.ts +226 -0
  107. package/src/Context.ts +585 -0
  108. package/src/Cron.ts +706 -0
  109. package/src/Data.ts +596 -0
  110. package/src/DateTime.ts +1686 -0
  111. package/src/DefaultServices.ts +34 -0
  112. package/src/Deferred.ts +301 -0
  113. package/src/Differ.ts +450 -0
  114. package/src/Duration.ts +1000 -0
  115. package/src/Effect.ts +14817 -0
  116. package/src/Effectable.ts +107 -0
  117. package/src/Either.ts +1040 -0
  118. package/src/Encoding.ts +195 -0
  119. package/src/Equal.ts +98 -0
  120. package/src/Equivalence.ts +235 -0
  121. package/src/ExecutionPlan.ts +308 -0
  122. package/src/ExecutionStrategy.ts +119 -0
  123. package/src/Exit.ts +467 -0
  124. package/src/FastCheck.ts +9 -0
  125. package/src/Fiber.ts +744 -0
  126. package/src/FiberHandle.ts +540 -0
  127. package/src/FiberId.ts +195 -0
  128. package/src/FiberMap.ts +656 -0
  129. package/src/FiberRef.ts +444 -0
  130. package/src/FiberRefs.ts +204 -0
  131. package/src/FiberRefsPatch.ts +105 -0
  132. package/src/FiberSet.ts +491 -0
  133. package/src/FiberStatus.ts +108 -0
  134. package/src/Function.ts +1222 -0
  135. package/src/GlobalValue.ts +53 -0
  136. package/src/Graph.ts +3732 -0
  137. package/src/GroupBy.ts +103 -0
  138. package/src/HKT.ts +45 -0
  139. package/src/Hash.ts +195 -0
  140. package/src/HashMap.ts +519 -0
  141. package/src/HashRing.ts +317 -0
  142. package/src/HashSet.ts +2346 -0
  143. package/src/Inspectable.ts +287 -0
  144. package/src/Iterable.ts +1119 -0
  145. package/src/JSONSchema.ts +1044 -0
  146. package/src/KeyedPool.ts +167 -0
  147. package/src/Layer.ts +1228 -0
  148. package/src/LayerMap.ts +436 -0
  149. package/src/List.ts +977 -0
  150. package/src/LogLevel.ts +285 -0
  151. package/src/LogSpan.ts +25 -0
  152. package/src/Logger.ts +702 -0
  153. package/src/Mailbox.ts +268 -0
  154. package/src/ManagedRuntime.ts +180 -0
  155. package/src/Match.ts +1477 -0
  156. package/src/MergeDecision.ts +95 -0
  157. package/src/MergeState.ts +172 -0
  158. package/src/MergeStrategy.ts +107 -0
  159. package/src/Metric.ts +780 -0
  160. package/src/MetricBoundaries.ts +69 -0
  161. package/src/MetricHook.ts +151 -0
  162. package/src/MetricKey.ts +224 -0
  163. package/src/MetricKeyType.ts +262 -0
  164. package/src/MetricLabel.ts +47 -0
  165. package/src/MetricPair.ts +71 -0
  166. package/src/MetricPolling.ts +148 -0
  167. package/src/MetricRegistry.ts +48 -0
  168. package/src/MetricState.ts +257 -0
  169. package/src/Micro.ts +4405 -0
  170. package/src/ModuleVersion.ts +18 -0
  171. package/src/MutableHashMap.ts +411 -0
  172. package/src/MutableHashSet.ts +706 -0
  173. package/src/MutableList.ts +297 -0
  174. package/src/MutableQueue.ts +227 -0
  175. package/src/MutableRef.ts +202 -0
  176. package/src/NonEmptyIterable.ts +32 -0
  177. package/src/Number.ts +1071 -0
  178. package/src/Option.ts +2170 -0
  179. package/src/Order.ts +373 -0
  180. package/src/Ordering.ts +111 -0
  181. package/src/ParseResult.ts +2031 -0
  182. package/src/PartitionedSemaphore.ts +200 -0
  183. package/src/Pipeable.ts +566 -0
  184. package/src/Pool.ts +204 -0
  185. package/src/Predicate.ts +1405 -0
  186. package/src/Pretty.ts +205 -0
  187. package/src/PrimaryKey.ts +23 -0
  188. package/src/PubSub.ts +182 -0
  189. package/src/Queue.ts +644 -0
  190. package/src/Random.ts +204 -0
  191. package/src/RateLimiter.ts +138 -0
  192. package/src/RcMap.ts +141 -0
  193. package/src/RcRef.ts +122 -0
  194. package/src/Readable.ts +93 -0
  195. package/src/Record.ts +1274 -0
  196. package/src/RedBlackTree.ts +421 -0
  197. package/src/Redacted.ts +144 -0
  198. package/src/Ref.ts +180 -0
  199. package/src/RegExp.ts +38 -0
  200. package/src/Reloadable.ts +127 -0
  201. package/src/Request.ts +347 -0
  202. package/src/RequestBlock.ts +118 -0
  203. package/src/RequestResolver.ts +366 -0
  204. package/src/Resource.ts +119 -0
  205. package/src/Runtime.ts +383 -0
  206. package/src/RuntimeFlags.ts +336 -0
  207. package/src/RuntimeFlagsPatch.ts +183 -0
  208. package/src/STM.ts +2045 -0
  209. package/src/Schedule.ts +2219 -0
  210. package/src/ScheduleDecision.ts +62 -0
  211. package/src/ScheduleInterval.ts +151 -0
  212. package/src/ScheduleIntervals.ts +122 -0
  213. package/src/Scheduler.ts +353 -0
  214. package/src/Schema.ts +10914 -0
  215. package/src/SchemaAST.ts +3043 -0
  216. package/src/Scope.ts +204 -0
  217. package/src/ScopedCache.ts +151 -0
  218. package/src/ScopedRef.ts +117 -0
  219. package/src/Secret.ts +88 -0
  220. package/src/SingleProducerAsyncInput.ts +67 -0
  221. package/src/Sink.ts +1461 -0
  222. package/src/SortedMap.ts +287 -0
  223. package/src/SortedSet.ts +390 -0
  224. package/src/SourceLocation.ts +108 -0
  225. package/src/Stream.ts +6468 -0
  226. package/src/StreamEmit.ts +136 -0
  227. package/src/StreamHaltStrategy.ts +123 -0
  228. package/src/Streamable.ts +45 -0
  229. package/src/String.ts +778 -0
  230. package/src/Struct.ts +243 -0
  231. package/src/Subscribable.ts +100 -0
  232. package/src/SubscriptionRef.ts +298 -0
  233. package/src/Supervisor.ts +240 -0
  234. package/src/Symbol.ts +29 -0
  235. package/src/SynchronizedRef.ts +270 -0
  236. package/src/TArray.ts +495 -0
  237. package/src/TDeferred.ts +100 -0
  238. package/src/TMap.ts +515 -0
  239. package/src/TPriorityQueue.ts +223 -0
  240. package/src/TPubSub.ts +200 -0
  241. package/src/TQueue.ts +432 -0
  242. package/src/TRandom.ts +129 -0
  243. package/src/TReentrantLock.ts +224 -0
  244. package/src/TRef.ts +178 -0
  245. package/src/TSemaphore.ts +129 -0
  246. package/src/TSet.ts +365 -0
  247. package/src/TSubscriptionRef.ts +192 -0
  248. package/src/Take.ts +258 -0
  249. package/src/TestAnnotation.ts +158 -0
  250. package/src/TestAnnotationMap.ts +119 -0
  251. package/src/TestAnnotations.ts +117 -0
  252. package/src/TestClock.ts +556 -0
  253. package/src/TestConfig.ts +47 -0
  254. package/src/TestContext.ts +36 -0
  255. package/src/TestLive.ts +53 -0
  256. package/src/TestServices.ts +390 -0
  257. package/src/TestSized.ts +55 -0
  258. package/src/Tracer.ts +182 -0
  259. package/src/Trie.ts +840 -0
  260. package/src/Tuple.ts +305 -0
  261. package/src/Types.ts +353 -0
  262. package/src/Unify.ts +113 -0
  263. package/src/UpstreamPullRequest.ts +117 -0
  264. package/src/UpstreamPullStrategy.ts +121 -0
  265. package/src/Utils.ts +809 -0
  266. package/src/index.ts +1568 -0
  267. package/src/internal/array.ts +8 -0
  268. package/src/internal/blockedRequests.ts +520 -0
  269. package/src/internal/cache.ts +733 -0
  270. package/src/internal/cause.ts +1050 -0
  271. package/src/internal/channel/channelExecutor.ts +1200 -0
  272. package/src/internal/channel/channelState.ts +134 -0
  273. package/src/internal/channel/childExecutorDecision.ts +96 -0
  274. package/src/internal/channel/continuation.ts +200 -0
  275. package/src/internal/channel/mergeDecision.ts +113 -0
  276. package/src/internal/channel/mergeState.ts +120 -0
  277. package/src/internal/channel/mergeStrategy.ts +72 -0
  278. package/src/internal/channel/singleProducerAsyncInput.ts +259 -0
  279. package/src/internal/channel/subexecutor.ts +229 -0
  280. package/src/internal/channel/upstreamPullRequest.ts +84 -0
  281. package/src/internal/channel/upstreamPullStrategy.ts +87 -0
  282. package/src/internal/channel.ts +2603 -0
  283. package/src/internal/clock.ts +95 -0
  284. package/src/internal/completedRequestMap.ts +9 -0
  285. package/src/internal/concurrency.ts +54 -0
  286. package/src/internal/config.ts +716 -0
  287. package/src/internal/configError.ts +304 -0
  288. package/src/internal/configProvider/pathPatch.ts +97 -0
  289. package/src/internal/configProvider.ts +799 -0
  290. package/src/internal/console.ts +153 -0
  291. package/src/internal/context.ts +337 -0
  292. package/src/internal/core-effect.ts +2293 -0
  293. package/src/internal/core-stream.ts +998 -0
  294. package/src/internal/core.ts +3189 -0
  295. package/src/internal/data.ts +36 -0
  296. package/src/internal/dataSource.ts +327 -0
  297. package/src/internal/dateTime.ts +1277 -0
  298. package/src/internal/defaultServices/console.ts +100 -0
  299. package/src/internal/defaultServices.ts +163 -0
  300. package/src/internal/deferred.ts +46 -0
  301. package/src/internal/differ/chunkPatch.ts +211 -0
  302. package/src/internal/differ/contextPatch.ts +232 -0
  303. package/src/internal/differ/hashMapPatch.ts +220 -0
  304. package/src/internal/differ/hashSetPatch.ts +176 -0
  305. package/src/internal/differ/orPatch.ts +311 -0
  306. package/src/internal/differ/readonlyArrayPatch.ts +210 -0
  307. package/src/internal/differ.ts +200 -0
  308. package/src/internal/doNotation.ts +80 -0
  309. package/src/internal/effect/circular.ts +895 -0
  310. package/src/internal/effectable.ts +131 -0
  311. package/src/internal/either.ts +110 -0
  312. package/src/internal/encoding/base64.ts +286 -0
  313. package/src/internal/encoding/base64Url.ts +29 -0
  314. package/src/internal/encoding/common.ts +51 -0
  315. package/src/internal/encoding/hex.ts +315 -0
  316. package/src/internal/errors.ts +7 -0
  317. package/src/internal/executionPlan.ts +114 -0
  318. package/src/internal/executionStrategy.ts +74 -0
  319. package/src/internal/fiber.ts +388 -0
  320. package/src/internal/fiberId.ts +267 -0
  321. package/src/internal/fiberMessage.ts +82 -0
  322. package/src/internal/fiberRefs/patch.ts +144 -0
  323. package/src/internal/fiberRefs.ts +297 -0
  324. package/src/internal/fiberRuntime.ts +3842 -0
  325. package/src/internal/fiberScope.ts +71 -0
  326. package/src/internal/fiberStatus.ts +119 -0
  327. package/src/internal/groupBy.ts +530 -0
  328. package/src/internal/hashMap/array.ts +49 -0
  329. package/src/internal/hashMap/bitwise.ts +32 -0
  330. package/src/internal/hashMap/config.ts +14 -0
  331. package/src/internal/hashMap/keySet.ts +8 -0
  332. package/src/internal/hashMap/node.ts +391 -0
  333. package/src/internal/hashMap.ts +586 -0
  334. package/src/internal/hashSet.ts +323 -0
  335. package/src/internal/keyedPool.ts +244 -0
  336. package/src/internal/layer/circular.ts +214 -0
  337. package/src/internal/layer.ts +1483 -0
  338. package/src/internal/logSpan.ts +20 -0
  339. package/src/internal/logger-circular.ts +24 -0
  340. package/src/internal/logger.ts +522 -0
  341. package/src/internal/mailbox.ts +561 -0
  342. package/src/internal/managedRuntime/circular.ts +6 -0
  343. package/src/internal/managedRuntime.ts +134 -0
  344. package/src/internal/matcher.ts +652 -0
  345. package/src/internal/metric/boundaries.ts +75 -0
  346. package/src/internal/metric/hook.ts +483 -0
  347. package/src/internal/metric/key.ts +167 -0
  348. package/src/internal/metric/keyType.ts +238 -0
  349. package/src/internal/metric/label.ts +41 -0
  350. package/src/internal/metric/pair.ts +48 -0
  351. package/src/internal/metric/polling.ts +149 -0
  352. package/src/internal/metric/registry.ts +187 -0
  353. package/src/internal/metric/state.ts +290 -0
  354. package/src/internal/metric.ts +577 -0
  355. package/src/internal/opCodes/cause.ts +35 -0
  356. package/src/internal/opCodes/channel.ts +83 -0
  357. package/src/internal/opCodes/channelChildExecutorDecision.ts +17 -0
  358. package/src/internal/opCodes/channelMergeDecision.ts +11 -0
  359. package/src/internal/opCodes/channelMergeState.ts +17 -0
  360. package/src/internal/opCodes/channelMergeStrategy.ts +11 -0
  361. package/src/internal/opCodes/channelState.ts +23 -0
  362. package/src/internal/opCodes/channelUpstreamPullRequest.ts +11 -0
  363. package/src/internal/opCodes/channelUpstreamPullStrategy.ts +11 -0
  364. package/src/internal/opCodes/config.ts +65 -0
  365. package/src/internal/opCodes/configError.ts +35 -0
  366. package/src/internal/opCodes/continuation.ts +11 -0
  367. package/src/internal/opCodes/deferred.ts +11 -0
  368. package/src/internal/opCodes/effect.ts +89 -0
  369. package/src/internal/opCodes/layer.ts +59 -0
  370. package/src/internal/opCodes/streamHaltStrategy.ts +23 -0
  371. package/src/internal/option.ts +80 -0
  372. package/src/internal/pool.ts +432 -0
  373. package/src/internal/pubsub.ts +1762 -0
  374. package/src/internal/query.ts +204 -0
  375. package/src/internal/queue.ts +766 -0
  376. package/src/internal/random.ts +161 -0
  377. package/src/internal/rateLimiter.ts +93 -0
  378. package/src/internal/rcMap.ts +285 -0
  379. package/src/internal/rcRef.ts +192 -0
  380. package/src/internal/redBlackTree/iterator.ts +200 -0
  381. package/src/internal/redBlackTree/node.ts +68 -0
  382. package/src/internal/redBlackTree.ts +1245 -0
  383. package/src/internal/redacted.ts +73 -0
  384. package/src/internal/ref.ts +171 -0
  385. package/src/internal/reloadable.ts +140 -0
  386. package/src/internal/request.ts +177 -0
  387. package/src/internal/resource.ts +76 -0
  388. package/src/internal/ringBuffer.ts +68 -0
  389. package/src/internal/runtime.ts +558 -0
  390. package/src/internal/runtimeFlags.ts +178 -0
  391. package/src/internal/runtimeFlagsPatch.ts +103 -0
  392. package/src/internal/schedule/decision.ts +47 -0
  393. package/src/internal/schedule/interval.ts +101 -0
  394. package/src/internal/schedule/intervals.ts +180 -0
  395. package/src/internal/schedule.ts +2199 -0
  396. package/src/internal/schema/errors.ts +191 -0
  397. package/src/internal/schema/schemaId.ts +106 -0
  398. package/src/internal/schema/util.ts +50 -0
  399. package/src/internal/scopedCache.ts +644 -0
  400. package/src/internal/scopedRef.ts +118 -0
  401. package/src/internal/secret.ts +89 -0
  402. package/src/internal/singleShotGen.ts +35 -0
  403. package/src/internal/sink.ts +2120 -0
  404. package/src/internal/stack.ts +10 -0
  405. package/src/internal/stm/core.ts +817 -0
  406. package/src/internal/stm/entry.ts +59 -0
  407. package/src/internal/stm/journal.ts +123 -0
  408. package/src/internal/stm/opCodes/stm.ts +71 -0
  409. package/src/internal/stm/opCodes/stmState.ts +17 -0
  410. package/src/internal/stm/opCodes/strategy.ts +17 -0
  411. package/src/internal/stm/opCodes/tExit.ts +29 -0
  412. package/src/internal/stm/opCodes/tryCommit.ts +11 -0
  413. package/src/internal/stm/stm.ts +1453 -0
  414. package/src/internal/stm/stmState.ts +136 -0
  415. package/src/internal/stm/tArray.ts +550 -0
  416. package/src/internal/stm/tDeferred.ts +81 -0
  417. package/src/internal/stm/tExit.ts +190 -0
  418. package/src/internal/stm/tMap.ts +824 -0
  419. package/src/internal/stm/tPriorityQueue.ts +267 -0
  420. package/src/internal/stm/tPubSub.ts +551 -0
  421. package/src/internal/stm/tQueue.ts +393 -0
  422. package/src/internal/stm/tRandom.ts +140 -0
  423. package/src/internal/stm/tReentrantLock.ts +352 -0
  424. package/src/internal/stm/tRef.ts +195 -0
  425. package/src/internal/stm/tSemaphore.ts +113 -0
  426. package/src/internal/stm/tSet.ts +259 -0
  427. package/src/internal/stm/tSubscriptionRef.ts +286 -0
  428. package/src/internal/stm/tryCommit.ts +34 -0
  429. package/src/internal/stm/txnId.ts +14 -0
  430. package/src/internal/stm/versioned.ts +4 -0
  431. package/src/internal/stream/debounceState.ts +57 -0
  432. package/src/internal/stream/emit.ts +123 -0
  433. package/src/internal/stream/haltStrategy.ts +94 -0
  434. package/src/internal/stream/handoff.ts +187 -0
  435. package/src/internal/stream/handoffSignal.ts +59 -0
  436. package/src/internal/stream/pull.ts +34 -0
  437. package/src/internal/stream/sinkEndReason.ts +30 -0
  438. package/src/internal/stream/zipAllState.ts +88 -0
  439. package/src/internal/stream/zipChunksState.ts +56 -0
  440. package/src/internal/stream.ts +8801 -0
  441. package/src/internal/string-utils.ts +107 -0
  442. package/src/internal/subscriptionRef.ts +138 -0
  443. package/src/internal/supervisor/patch.ts +190 -0
  444. package/src/internal/supervisor.ts +303 -0
  445. package/src/internal/synchronizedRef.ts +114 -0
  446. package/src/internal/take.ts +199 -0
  447. package/src/internal/testing/sleep.ts +27 -0
  448. package/src/internal/testing/suspendedWarningData.ts +85 -0
  449. package/src/internal/testing/warningData.ts +94 -0
  450. package/src/internal/tracer.ts +150 -0
  451. package/src/internal/trie.ts +722 -0
  452. package/src/internal/version.ts +7 -0
package/src/Array.ts ADDED
@@ -0,0 +1,3589 @@
1
+ /**
2
+ * This module provides utility functions for working with arrays in TypeScript.
3
+ *
4
+ * @since 2.0.0
5
+ */
6
+
7
+ import * as Either from "./Either.js"
8
+ import * as Equal from "./Equal.js"
9
+ import * as Equivalence from "./Equivalence.js"
10
+ import type { LazyArg } from "./Function.js"
11
+ import { dual, identity } from "./Function.js"
12
+ import type { TypeLambda } from "./HKT.js"
13
+ import * as internalArray from "./internal/array.js"
14
+ import * as internalDoNotation from "./internal/doNotation.js"
15
+ import * as moduleIterable from "./Iterable.js"
16
+ import * as Option from "./Option.js"
17
+ import * as Order from "./Order.js"
18
+ import * as Predicate from "./Predicate.js"
19
+ import * as Record from "./Record.js"
20
+ import * as Tuple from "./Tuple.js"
21
+ import type { NoInfer, TupleOf } from "./Types.js"
22
+
23
+ /**
24
+ * @category type lambdas
25
+ * @since 2.0.0
26
+ */
27
+ export interface ReadonlyArrayTypeLambda extends TypeLambda {
28
+ readonly type: ReadonlyArray<this["Target"]>
29
+ }
30
+
31
+ /**
32
+ * @category models
33
+ * @since 2.0.0
34
+ */
35
+ export type NonEmptyReadonlyArray<A> = readonly [A, ...Array<A>]
36
+
37
+ /**
38
+ * @category models
39
+ * @since 2.0.0
40
+ */
41
+ export type NonEmptyArray<A> = [A, ...Array<A>]
42
+
43
+ /**
44
+ * Builds a `NonEmptyArray` from an non-empty collection of elements.
45
+ *
46
+ * **Example**
47
+ *
48
+ * ```ts
49
+ * import { Array } from "effect"
50
+ *
51
+ * const result = Array.make(1, 2, 3)
52
+ * console.log(result) // [1, 2, 3]
53
+ * ```
54
+ *
55
+ * @category constructors
56
+ * @since 2.0.0
57
+ */
58
+ export const make = <Elements extends NonEmptyArray<any>>(
59
+ ...elements: Elements
60
+ ): NonEmptyArray<Elements[number]> => elements
61
+
62
+ /**
63
+ * Creates a new `Array` of the specified length.
64
+ *
65
+ * **Example**
66
+ *
67
+ * ```ts
68
+ * import { Array } from "effect"
69
+ *
70
+ * const result = Array.allocate<number>(3)
71
+ * console.log(result) // [ <3 empty items> ]
72
+ * ```
73
+ *
74
+ * @category constructors
75
+ * @since 2.0.0
76
+ */
77
+ export const allocate = <A = never>(n: number): Array<A | undefined> => new Array(n)
78
+
79
+ /**
80
+ * Return a `NonEmptyArray` of length `n` with element `i` initialized with `f(i)`.
81
+ *
82
+ * **Note**. `n` is normalized to an integer >= 1.
83
+ *
84
+ * **Example**
85
+ *
86
+ * ```ts
87
+ * import { makeBy } from "effect/Array"
88
+ *
89
+ * const result = makeBy(5, n => n * 2)
90
+ * console.log(result) // [0, 2, 4, 6, 8]
91
+ * ```
92
+ *
93
+ * @category constructors
94
+ * @since 2.0.0
95
+ */
96
+ export const makeBy: {
97
+ <A>(f: (i: number) => A): (n: number) => NonEmptyArray<A>
98
+ <A>(n: number, f: (i: number) => A): NonEmptyArray<A>
99
+ } = dual(2, <A>(n: number, f: (i: number) => A) => {
100
+ const max = Math.max(1, Math.floor(n))
101
+ const out = new Array(max)
102
+ for (let i = 0; i < max; i++) {
103
+ out[i] = f(i)
104
+ }
105
+ return out as NonEmptyArray<A>
106
+ })
107
+
108
+ /**
109
+ * Return a `NonEmptyArray` containing a range of integers, including both endpoints.
110
+ *
111
+ * **Example**
112
+ *
113
+ * ```ts
114
+ * import { range } from "effect/Array"
115
+ *
116
+ * const result = range(1, 3)
117
+ * console.log(result) // [1, 2, 3]
118
+ * ```
119
+ *
120
+ * @category constructors
121
+ * @since 2.0.0
122
+ */
123
+ export const range = (start: number, end: number): NonEmptyArray<number> =>
124
+ start <= end ? makeBy(end - start + 1, (i) => start + i) : [start]
125
+
126
+ /**
127
+ * Return a `NonEmptyArray` containing a value repeated the specified number of times.
128
+ *
129
+ * **Note**. `n` is normalized to an integer >= 1.
130
+ *
131
+ * **Example**
132
+ *
133
+ * ```ts
134
+ * import { Array } from "effect"
135
+ *
136
+ * const result = Array.replicate("a", 3)
137
+ * console.log(result) // ["a", "a", "a"]
138
+ * ```
139
+ *
140
+ * @category constructors
141
+ * @since 2.0.0
142
+ */
143
+ export const replicate: {
144
+ (n: number): <A>(a: A) => NonEmptyArray<A>
145
+ <A>(a: A, n: number): NonEmptyArray<A>
146
+ } = dual(2, <A>(a: A, n: number): NonEmptyArray<A> => makeBy(n, () => a))
147
+
148
+ /**
149
+ * Creates a new `Array` from an iterable collection of values.
150
+ * If the input is already an array, it returns the input as-is.
151
+ * Otherwise, it converts the iterable collection to an array.
152
+ *
153
+ * **Example**
154
+ *
155
+ * ```ts
156
+ * import { Array } from "effect"
157
+ *
158
+ * const result = Array.fromIterable(new Set([1, 2, 3]))
159
+ * console.log(result) // [1, 2, 3]
160
+ * ```
161
+ *
162
+ * @category constructors
163
+ * @since 2.0.0
164
+ */
165
+ export const fromIterable = <A>(collection: Iterable<A>): Array<A> =>
166
+ Array.isArray(collection) ? collection : Array.from(collection)
167
+
168
+ /**
169
+ * Creates a new `Array` from a value that might not be an iterable.
170
+ *
171
+ * **Example**
172
+ *
173
+ * ```ts
174
+ * import { Array } from "effect"
175
+ *
176
+ * console.log(Array.ensure("a")) // ["a"]
177
+ * console.log(Array.ensure(["a"])) // ["a"]
178
+ * console.log(Array.ensure(["a", "b", "c"])) // ["a", "b", "c"]
179
+ * ```
180
+ *
181
+ * @category constructors
182
+ * @since 3.3.0
183
+ */
184
+ export const ensure = <A>(self: ReadonlyArray<A> | A): Array<A> => Array.isArray(self) ? self : [self as A]
185
+
186
+ /**
187
+ * Takes a record and returns an array of tuples containing its keys and values.
188
+ *
189
+ * **Example**
190
+ *
191
+ * ```ts
192
+ * import { Array } from "effect"
193
+ *
194
+ * const result = Array.fromRecord({ a: 1, b: 2, c: 3 })
195
+ * console.log(result) // [["a", 1], ["b", 2], ["c", 3]]
196
+ * ```
197
+ *
198
+ * @category conversions
199
+ * @since 2.0.0
200
+ */
201
+ export const fromRecord: <K extends string, A>(self: Readonly<Record<K, A>>) => Array<[K, A]> = Record.toEntries
202
+
203
+ /**
204
+ * Converts an `Option` to an array.
205
+ *
206
+ * **Example**
207
+ *
208
+ * ```ts
209
+ * import { Array, Option } from "effect"
210
+ *
211
+ * console.log(Array.fromOption(Option.some(1))) // [1]
212
+ * console.log(Array.fromOption(Option.none())) // []
213
+ * ```
214
+ *
215
+ * @category conversions
216
+ * @since 2.0.0
217
+ */
218
+ export const fromOption: <A>(self: Option.Option<A>) => Array<A> = Option.toArray
219
+
220
+ /**
221
+ * Matches the elements of an array, applying functions to cases of empty and non-empty arrays.
222
+ *
223
+ * **Example**
224
+ *
225
+ * ```ts
226
+ * import { Array } from "effect"
227
+ *
228
+ * const match = Array.match({
229
+ * onEmpty: () => "empty",
230
+ * onNonEmpty: ([head, ...tail]) => `head: ${head}, tail: ${tail.length}`
231
+ * })
232
+ * console.log(match([])) // "empty"
233
+ * console.log(match([1, 2, 3])) // "head: 1, tail: 2"
234
+ * ```
235
+ *
236
+ * @category pattern matching
237
+ * @since 2.0.0
238
+ */
239
+ export const match: {
240
+ <B, A, C = B>(
241
+ options: {
242
+ readonly onEmpty: LazyArg<B>
243
+ readonly onNonEmpty: (self: NonEmptyReadonlyArray<A>) => C
244
+ }
245
+ ): (self: ReadonlyArray<A>) => B | C
246
+ <A, B, C = B>(
247
+ self: ReadonlyArray<A>,
248
+ options: {
249
+ readonly onEmpty: LazyArg<B>
250
+ readonly onNonEmpty: (self: NonEmptyReadonlyArray<A>) => C
251
+ }
252
+ ): B | C
253
+ } = dual(2, <A, B, C = B>(
254
+ self: ReadonlyArray<A>,
255
+ { onEmpty, onNonEmpty }: {
256
+ readonly onEmpty: LazyArg<B>
257
+ readonly onNonEmpty: (self: NonEmptyReadonlyArray<A>) => C
258
+ }
259
+ ): B | C => isNonEmptyReadonlyArray(self) ? onNonEmpty(self) : onEmpty())
260
+
261
+ /**
262
+ * Matches the elements of an array from the left, applying functions to cases of empty and non-empty arrays.
263
+ *
264
+ * **Example**
265
+ *
266
+ * ```ts
267
+ * import { Array } from "effect"
268
+ *
269
+ * const matchLeft = Array.matchLeft({
270
+ * onEmpty: () => "empty",
271
+ * onNonEmpty: (head, tail) => `head: ${head}, tail: ${tail.length}`
272
+ * })
273
+ * console.log(matchLeft([])) // "empty"
274
+ * console.log(matchLeft([1, 2, 3])) // "head: 1, tail: 2"
275
+ * ```
276
+ *
277
+ * @category pattern matching
278
+ * @since 2.0.0
279
+ */
280
+ export const matchLeft: {
281
+ <B, A, C = B>(
282
+ options: {
283
+ readonly onEmpty: LazyArg<B>
284
+ readonly onNonEmpty: (head: A, tail: Array<A>) => C
285
+ }
286
+ ): (self: ReadonlyArray<A>) => B | C
287
+ <A, B, C = B>(
288
+ self: ReadonlyArray<A>,
289
+ options: {
290
+ readonly onEmpty: LazyArg<B>
291
+ readonly onNonEmpty: (head: A, tail: Array<A>) => C
292
+ }
293
+ ): B | C
294
+ } = dual(2, <A, B, C = B>(
295
+ self: ReadonlyArray<A>,
296
+ { onEmpty, onNonEmpty }: {
297
+ readonly onEmpty: LazyArg<B>
298
+ readonly onNonEmpty: (head: A, tail: Array<A>) => C
299
+ }
300
+ ): B | C => isNonEmptyReadonlyArray(self) ? onNonEmpty(headNonEmpty(self), tailNonEmpty(self)) : onEmpty())
301
+
302
+ /**
303
+ * Matches the elements of an array from the right, applying functions to cases of empty and non-empty arrays.
304
+ *
305
+ * **Example**
306
+ *
307
+ * ```ts
308
+ * import { Array } from "effect"
309
+ *
310
+ * const matchRight = Array.matchRight({
311
+ * onEmpty: () => "empty",
312
+ * onNonEmpty: (init, last) => `init: ${init.length}, last: ${last}`
313
+ * })
314
+ * console.log(matchRight([])) // "empty"
315
+ * console.log(matchRight([1, 2, 3])) // "init: 2, last: 3"
316
+ * ```
317
+ *
318
+ * @category pattern matching
319
+ * @since 2.0.0
320
+ */
321
+ export const matchRight: {
322
+ <B, A, C = B>(
323
+ options: {
324
+ readonly onEmpty: LazyArg<B>
325
+ readonly onNonEmpty: (init: Array<A>, last: A) => C
326
+ }
327
+ ): (self: ReadonlyArray<A>) => B | C
328
+ <A, B, C = B>(
329
+ self: ReadonlyArray<A>,
330
+ options: {
331
+ readonly onEmpty: LazyArg<B>
332
+ readonly onNonEmpty: (init: Array<A>, last: A) => C
333
+ }
334
+ ): B | C
335
+ } = dual(2, <A, B, C = B>(
336
+ self: ReadonlyArray<A>,
337
+ { onEmpty, onNonEmpty }: {
338
+ readonly onEmpty: LazyArg<B>
339
+ readonly onNonEmpty: (init: Array<A>, last: A) => C
340
+ }
341
+ ): B | C =>
342
+ isNonEmptyReadonlyArray(self) ?
343
+ onNonEmpty(initNonEmpty(self), lastNonEmpty(self)) :
344
+ onEmpty())
345
+
346
+ /**
347
+ * Prepend an element to the front of an `Iterable`, creating a new `NonEmptyArray`.
348
+ *
349
+ * **Example**
350
+ *
351
+ * ```ts
352
+ * import { Array } from "effect"
353
+ *
354
+ * const result = Array.prepend([2, 3, 4], 1)
355
+ * console.log(result) // [1, 2, 3, 4]
356
+ * ```
357
+ *
358
+ * @category concatenating
359
+ * @since 2.0.0
360
+ */
361
+ export const prepend: {
362
+ <B>(head: B): <A>(self: Iterable<A>) => NonEmptyArray<A | B>
363
+ <A, B>(self: Iterable<A>, head: B): NonEmptyArray<A | B>
364
+ } = dual(2, <A, B>(self: Iterable<A>, head: B): NonEmptyArray<A | B> => [head, ...self])
365
+
366
+ /**
367
+ * Prepends the specified prefix array (or iterable) to the beginning of the specified array (or iterable).
368
+ * If either array is non-empty, the result is also a non-empty array.
369
+ *
370
+ * **Example**
371
+ *
372
+ * ```ts
373
+ * import { Array } from "effect"
374
+ *
375
+ * const result = Array.prependAll([2, 3], [0, 1])
376
+ * console.log(result) // [0, 1, 2, 3]
377
+ * ```
378
+ *
379
+ * @category concatenating
380
+ * @since 2.0.0
381
+ */
382
+ export const prependAll: {
383
+ <S extends Iterable<any>, T extends Iterable<any>>(
384
+ that: T
385
+ ): (self: S) => ReadonlyArray.OrNonEmpty<S, T, ReadonlyArray.Infer<S> | ReadonlyArray.Infer<T>>
386
+ <A, B>(self: Iterable<A>, that: NonEmptyReadonlyArray<B>): NonEmptyArray<A | B>
387
+ <A, B>(self: NonEmptyReadonlyArray<A>, that: Iterable<B>): NonEmptyArray<A | B>
388
+ <A, B>(self: Iterable<A>, that: Iterable<B>): Array<A | B>
389
+ } = dual(
390
+ 2,
391
+ <A>(self: Iterable<A>, that: Iterable<A>): Array<A> => fromIterable(that).concat(fromIterable(self))
392
+ )
393
+
394
+ /**
395
+ * Append an element to the end of an `Iterable`, creating a new `NonEmptyArray`.
396
+ *
397
+ * **Example**
398
+ *
399
+ * ```ts
400
+ * import { Array } from "effect"
401
+ *
402
+ * const result = Array.append([1, 2, 3], 4);
403
+ * console.log(result) // [1, 2, 3, 4]
404
+ * ```
405
+ *
406
+ * @category concatenating
407
+ * @since 2.0.0
408
+ */
409
+ export const append: {
410
+ <B>(last: B): <A>(self: Iterable<A>) => NonEmptyArray<A | B>
411
+ <A, B>(self: Iterable<A>, last: B): NonEmptyArray<A | B>
412
+ } = dual(2, <A, B>(self: Iterable<A>, last: B): Array<A | B> => [...self, last])
413
+
414
+ /**
415
+ * Concatenates two arrays (or iterables), combining their elements.
416
+ * If either array is non-empty, the result is also a non-empty array.
417
+ *
418
+ * @category concatenating
419
+ * @since 2.0.0
420
+ */
421
+ export const appendAll: {
422
+ <S extends Iterable<any>, T extends Iterable<any>>(
423
+ that: T
424
+ ): (self: S) => ReadonlyArray.OrNonEmpty<S, T, ReadonlyArray.Infer<S> | ReadonlyArray.Infer<T>>
425
+ <A, B>(self: Iterable<A>, that: NonEmptyReadonlyArray<B>): NonEmptyArray<A | B>
426
+ <A, B>(self: NonEmptyReadonlyArray<A>, that: Iterable<B>): NonEmptyArray<A | B>
427
+ <A, B>(self: Iterable<A>, that: Iterable<B>): Array<A | B>
428
+ } = dual(
429
+ 2,
430
+ <A>(self: Iterable<A>, that: Iterable<A>): Array<A> => fromIterable(self).concat(fromIterable(that))
431
+ )
432
+
433
+ /**
434
+ * Accumulates values from an `Iterable` starting from the left, storing
435
+ * each intermediate result in an array. Useful for tracking the progression of
436
+ * a value through a series of transformations.
437
+ *
438
+ * **Example**
439
+ *
440
+ * ```ts
441
+ * import { Array } from "effect";
442
+ *
443
+ * const result = Array.scan([1, 2, 3, 4], 0, (acc, value) => acc + value)
444
+ * console.log(result) // [0, 1, 3, 6, 10]
445
+ *
446
+ * // Explanation:
447
+ * // This function starts with the initial value (0 in this case)
448
+ * // and adds each element of the array to this accumulator one by one,
449
+ * // keeping track of the cumulative sum after each addition.
450
+ * // Each of these sums is captured in the resulting array.
451
+ * ```
452
+ *
453
+ * @category folding
454
+ * @since 2.0.0
455
+ */
456
+ export const scan: {
457
+ <B, A>(b: B, f: (b: B, a: A) => B): (self: Iterable<A>) => NonEmptyArray<B>
458
+ <A, B>(self: Iterable<A>, b: B, f: (b: B, a: A) => B): NonEmptyArray<B>
459
+ } = dual(3, <A, B>(self: Iterable<A>, b: B, f: (b: B, a: A) => B): NonEmptyArray<B> => {
460
+ const out: NonEmptyArray<B> = [b]
461
+ let i = 0
462
+ for (const a of self) {
463
+ out[i + 1] = f(out[i], a)
464
+ i++
465
+ }
466
+ return out
467
+ })
468
+
469
+ /**
470
+ * Accumulates values from an `Iterable` starting from the right, storing
471
+ * each intermediate result in an array. Useful for tracking the progression of
472
+ * a value through a series of transformations.
473
+ *
474
+ * **Example**
475
+ *
476
+ * ```ts
477
+ * import { Array } from "effect";
478
+ *
479
+ * const result = Array.scanRight([1, 2, 3, 4], 0, (acc, value) => acc + value)
480
+ * console.log(result) // [10, 9, 7, 4, 0]
481
+ * ```
482
+ *
483
+ * @category folding
484
+ * @since 2.0.0
485
+ */
486
+ export const scanRight: {
487
+ <B, A>(b: B, f: (b: B, a: A) => B): (self: Iterable<A>) => NonEmptyArray<B>
488
+ <A, B>(self: Iterable<A>, b: B, f: (b: B, a: A) => B): NonEmptyArray<B>
489
+ } = dual(3, <A, B>(self: Iterable<A>, b: B, f: (b: B, a: A) => B): NonEmptyArray<B> => {
490
+ const input = fromIterable(self)
491
+ const out: NonEmptyArray<B> = new Array(input.length + 1) as any
492
+ out[input.length] = b
493
+ for (let i = input.length - 1; i >= 0; i--) {
494
+ out[i] = f(out[i + 1], input[i])
495
+ }
496
+ return out
497
+ })
498
+
499
+ /**
500
+ * Determine if `unknown` is an Array.
501
+ *
502
+ * **Example**
503
+ *
504
+ * ```ts
505
+ * import { Array } from "effect"
506
+ *
507
+ * console.log(Array.isArray(null)) // false
508
+ * console.log(Array.isArray([1, 2, 3])) // true
509
+ * ```
510
+ *
511
+ * @category guards
512
+ * @since 2.0.0
513
+ */
514
+ export const isArray: {
515
+ (self: unknown): self is Array<unknown>
516
+ <T>(self: T): self is Extract<T, ReadonlyArray<any>>
517
+ } = Array.isArray
518
+
519
+ /**
520
+ * Determine if an `Array` is empty narrowing down the type to `[]`.
521
+ *
522
+ * **Example**
523
+ *
524
+ * ```ts
525
+ * import { Array } from "effect"
526
+ *
527
+ * console.log(Array.isEmptyArray([])) // true
528
+ * console.log(Array.isEmptyArray([1, 2, 3])) // false
529
+ * ```
530
+ *
531
+ * @category guards
532
+ * @since 2.0.0
533
+ */
534
+ export const isEmptyArray = <A>(self: Array<A>): self is [] => self.length === 0
535
+
536
+ /**
537
+ * Determine if a `ReadonlyArray` is empty narrowing down the type to `readonly []`.
538
+ *
539
+ * **Example**
540
+ *
541
+ * ```ts
542
+ * import { Array } from "effect"
543
+ *
544
+ * console.log(Array.isEmptyReadonlyArray([])) // true
545
+ * console.log(Array.isEmptyReadonlyArray([1, 2, 3])) // false
546
+ * ```
547
+ *
548
+ * @category guards
549
+ * @since 2.0.0
550
+ */
551
+ export const isEmptyReadonlyArray: <A>(self: ReadonlyArray<A>) => self is readonly [] = isEmptyArray as any
552
+
553
+ /**
554
+ * Determine if an `Array` is non empty narrowing down the type to `NonEmptyArray`.
555
+ *
556
+ * An `Array` is considered to be a `NonEmptyArray` if it contains at least one element.
557
+ *
558
+ * **Example**
559
+ *
560
+ * ```ts
561
+ * import { Array } from "effect"
562
+ *
563
+ * console.log(Array.isNonEmptyArray([])) // false
564
+ * console.log(Array.isNonEmptyArray([1, 2, 3])) // true
565
+ * ```
566
+ *
567
+ * @category guards
568
+ * @since 2.0.0
569
+ */
570
+ export const isNonEmptyArray: <A>(self: Array<A>) => self is NonEmptyArray<A> = internalArray.isNonEmptyArray
571
+
572
+ /**
573
+ * Determine if a `ReadonlyArray` is non empty narrowing down the type to `NonEmptyReadonlyArray`.
574
+ *
575
+ * A `ReadonlyArray` is considered to be a `NonEmptyReadonlyArray` if it contains at least one element.
576
+ *
577
+ * **Example**
578
+ *
579
+ * ```ts
580
+ * import { Array } from "effect"
581
+ *
582
+ * console.log(Array.isNonEmptyReadonlyArray([])) // false
583
+ * console.log(Array.isNonEmptyReadonlyArray([1, 2, 3])) // true
584
+ * ```
585
+ *
586
+ * @category guards
587
+ * @since 2.0.0
588
+ */
589
+ export const isNonEmptyReadonlyArray: <A>(self: ReadonlyArray<A>) => self is NonEmptyReadonlyArray<A> =
590
+ internalArray.isNonEmptyArray
591
+
592
+ /**
593
+ * Return the number of elements in a `ReadonlyArray`.
594
+ *
595
+ * @category getters
596
+ * @since 2.0.0
597
+ */
598
+ export const length = <A>(self: ReadonlyArray<A>): number => self.length
599
+
600
+ const isOutOfBounds = <A>(i: number, as: ReadonlyArray<A>): boolean => i < 0 || i >= as.length
601
+
602
+ const clamp = <A>(i: number, as: ReadonlyArray<A>): number => Math.floor(Math.min(Math.max(0, i), as.length))
603
+
604
+ /**
605
+ * This function provides a safe way to read a value at a particular index from a `ReadonlyArray`.
606
+ *
607
+ * @category getters
608
+ * @since 2.0.0
609
+ */
610
+ export const get: {
611
+ (index: number): <A>(self: ReadonlyArray<A>) => Option.Option<A>
612
+ <A>(self: ReadonlyArray<A>, index: number): Option.Option<A>
613
+ } = dual(2, <A>(self: ReadonlyArray<A>, index: number): Option.Option<A> => {
614
+ const i = Math.floor(index)
615
+ return isOutOfBounds(i, self) ? Option.none() : Option.some(self[i])
616
+ })
617
+
618
+ /**
619
+ * Gets an element unsafely, will throw on out of bounds.
620
+ *
621
+ * @since 2.0.0
622
+ * @category unsafe
623
+ */
624
+ export const unsafeGet: {
625
+ (index: number): <A>(self: ReadonlyArray<A>) => A
626
+ <A>(self: ReadonlyArray<A>, index: number): A
627
+ } = dual(2, <A>(self: ReadonlyArray<A>, index: number): A => {
628
+ const i = Math.floor(index)
629
+ if (isOutOfBounds(i, self)) {
630
+ throw new Error(`Index ${i} out of bounds`)
631
+ }
632
+ return self[i]
633
+ })
634
+
635
+ /**
636
+ * Return a tuple containing the first element, and a new `Array` of the remaining elements, if any.
637
+ *
638
+ * **Example**
639
+ *
640
+ * ```ts
641
+ * import { Array } from "effect";
642
+ *
643
+ * const result = Array.unprepend([1, 2, 3, 4])
644
+ * console.log(result) // [1, [2, 3, 4]]
645
+ * ```
646
+ *
647
+ * @category splitting
648
+ * @since 2.0.0
649
+ */
650
+ export const unprepend = <A>(
651
+ self: NonEmptyReadonlyArray<A>
652
+ ): [firstElement: A, remainingElements: Array<A>] => [headNonEmpty(self), tailNonEmpty(self)]
653
+
654
+ /**
655
+ * Return a tuple containing a copy of the `NonEmptyReadonlyArray` without its last element, and that last element.
656
+ *
657
+ * **Example**
658
+ *
659
+ * ```ts
660
+ * import { Array } from "effect";
661
+ *
662
+ * const result = Array.unappend([1, 2, 3, 4])
663
+ * console.log(result) // [[1, 2, 3], 4]
664
+ * ```
665
+ *
666
+ * @category splitting
667
+ * @since 2.0.0
668
+ */
669
+ export const unappend = <A>(
670
+ self: NonEmptyReadonlyArray<A>
671
+ ): [arrayWithoutLastElement: Array<A>, lastElement: A] => [initNonEmpty(self), lastNonEmpty(self)]
672
+
673
+ /**
674
+ * Get the first element of a `ReadonlyArray`, or `None` if the `ReadonlyArray` is empty.
675
+ *
676
+ * @category getters
677
+ * @since 2.0.0
678
+ */
679
+ export const head: <A>(self: ReadonlyArray<A>) => Option.Option<A> = get(0)
680
+
681
+ /**
682
+ * Get the first element of a non empty array.
683
+ *
684
+ * **Example**
685
+ *
686
+ * ```ts
687
+ * import { Array } from "effect"
688
+ *
689
+ * const result = Array.headNonEmpty([1, 2, 3, 4])
690
+ * console.log(result) // 1
691
+ * ```
692
+ *
693
+ * @category getters
694
+ * @since 2.0.0
695
+ */
696
+ export const headNonEmpty: <A>(self: NonEmptyReadonlyArray<A>) => A = unsafeGet(0)
697
+
698
+ /**
699
+ * Get the last element in a `ReadonlyArray`, or `None` if the `ReadonlyArray` is empty.
700
+ *
701
+ * @category getters
702
+ * @since 2.0.0
703
+ */
704
+ export const last = <A>(self: ReadonlyArray<A>): Option.Option<A> =>
705
+ isNonEmptyReadonlyArray(self) ? Option.some(lastNonEmpty(self)) : Option.none()
706
+
707
+ /**
708
+ * Get the last element of a non empty array.
709
+ *
710
+ * **Example**
711
+ *
712
+ * ```ts
713
+ * import { Array } from "effect"
714
+ *
715
+ * const result = Array.lastNonEmpty([1, 2, 3, 4])
716
+ * console.log(result) // 4
717
+ * ```
718
+ *
719
+ * @category getters
720
+ * @since 2.0.0
721
+ */
722
+ export const lastNonEmpty = <A>(self: NonEmptyReadonlyArray<A>): A => self[self.length - 1]
723
+
724
+ /**
725
+ * Get all but the first element of an `Iterable`, creating a new `Array`, or `None` if the `Iterable` is empty.
726
+ *
727
+ * @category getters
728
+ * @since 2.0.0
729
+ */
730
+ export const tail = <A>(self: Iterable<A>): Option.Option<Array<A>> => {
731
+ const input = fromIterable(self)
732
+ return isNonEmptyReadonlyArray(input) ? Option.some(tailNonEmpty(input)) : Option.none()
733
+ }
734
+
735
+ /**
736
+ * Get all but the first element of a `NonEmptyReadonlyArray`.
737
+ *
738
+ * **Example**
739
+ *
740
+ * ```ts
741
+ * import { Array } from "effect"
742
+ *
743
+ * const result = Array.tailNonEmpty([1, 2, 3, 4])
744
+ * console.log(result) // [2, 3, 4]
745
+ * ```
746
+ *
747
+ * @category getters
748
+ * @since 2.0.0
749
+ */
750
+ export const tailNonEmpty = <A>(self: NonEmptyReadonlyArray<A>): Array<A> => self.slice(1)
751
+
752
+ /**
753
+ * Get all but the last element of an `Iterable`, creating a new `Array`, or `None` if the `Iterable` is empty.
754
+ *
755
+ * @category getters
756
+ * @since 2.0.0
757
+ */
758
+ export const init = <A>(self: Iterable<A>): Option.Option<Array<A>> => {
759
+ const input = fromIterable(self)
760
+ return isNonEmptyReadonlyArray(input) ? Option.some(initNonEmpty(input)) : Option.none()
761
+ }
762
+
763
+ /**
764
+ * Get all but the last element of a non empty array, creating a new array.
765
+ *
766
+ * **Example**
767
+ *
768
+ * ```ts
769
+ * import { Array } from "effect"
770
+ *
771
+ * const result = Array.initNonEmpty([1, 2, 3, 4])
772
+ * console.log(result) // [1, 2, 3]
773
+ * ```
774
+ *
775
+ * @category getters
776
+ * @since 2.0.0
777
+ */
778
+ export const initNonEmpty = <A>(self: NonEmptyReadonlyArray<A>): Array<A> => self.slice(0, -1)
779
+
780
+ /**
781
+ * Keep only a max number of elements from the start of an `Iterable`, creating a new `Array`.
782
+ *
783
+ * **Note**. `n` is normalized to a non negative integer.
784
+ *
785
+ * **Example**
786
+ *
787
+ * ```ts
788
+ * import { Array } from "effect"
789
+ *
790
+ * const result = Array.take([1, 2, 3, 4, 5], 3)
791
+ * console.log(result) // [1, 2, 3]
792
+ * ```
793
+ *
794
+ * @category getters
795
+ * @since 2.0.0
796
+ */
797
+ export const take: {
798
+ (n: number): <A>(self: Iterable<A>) => Array<A>
799
+ <A>(self: Iterable<A>, n: number): Array<A>
800
+ } = dual(2, <A>(self: Iterable<A>, n: number): Array<A> => {
801
+ const input = fromIterable(self)
802
+ return input.slice(0, clamp(n, input))
803
+ })
804
+
805
+ /**
806
+ * Keep only a max number of elements from the end of an `Iterable`, creating a new `Array`.
807
+ *
808
+ * **Note**. `n` is normalized to a non negative integer.
809
+ *
810
+ * **Example**
811
+ *
812
+ * ```ts
813
+ * import { Array } from "effect"
814
+ *
815
+ * const result = Array.takeRight([1, 2, 3, 4, 5], 3)
816
+ * console.log(result) // [3, 4, 5]
817
+ * ```
818
+ *
819
+ * @category getters
820
+ * @since 2.0.0
821
+ */
822
+ export const takeRight: {
823
+ (n: number): <A>(self: Iterable<A>) => Array<A>
824
+ <A>(self: Iterable<A>, n: number): Array<A>
825
+ } = dual(2, <A>(self: Iterable<A>, n: number): Array<A> => {
826
+ const input = fromIterable(self)
827
+ const i = clamp(n, input)
828
+ return i === 0 ? [] : input.slice(-i)
829
+ })
830
+
831
+ /**
832
+ * Calculate the longest initial subarray for which all element satisfy the specified predicate, creating a new `Array`.
833
+ *
834
+ * **Example**
835
+ *
836
+ * ```ts
837
+ * import { Array } from "effect"
838
+ *
839
+ * const result = Array.takeWhile([1, 3, 2, 4, 1, 2], x => x < 4)
840
+ * console.log(result) // [1, 3, 2]
841
+ *
842
+ * // Explanation:
843
+ * // - The function starts with the first element (`1`), which is less than `4`, so it adds `1` to the result.
844
+ * // - The next element (`3`) is also less than `4`, so it adds `3`.
845
+ * // - The next element (`2`) is again less than `4`, so it adds `2`.
846
+ * // - The function then encounters `4`, which is not less than `4`. At this point, it stops checking further elements and finalizes the result.
847
+ * ```
848
+ *
849
+ * @category getters
850
+ * @since 2.0.0
851
+ */
852
+ export const takeWhile: {
853
+ <A, B extends A>(refinement: (a: NoInfer<A>, i: number) => a is B): (self: Iterable<A>) => Array<B>
854
+ <A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Array<A>
855
+ <A, B extends A>(self: Iterable<A>, refinement: (a: A, i: number) => a is B): Array<B>
856
+ <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Array<A>
857
+ } = dual(2, <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Array<A> => {
858
+ let i = 0
859
+ const out: Array<A> = []
860
+ for (const a of self) {
861
+ if (!predicate(a, i)) {
862
+ break
863
+ }
864
+ out.push(a)
865
+ i++
866
+ }
867
+ return out
868
+ })
869
+
870
+ const spanIndex = <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): number => {
871
+ let i = 0
872
+ for (const a of self) {
873
+ if (!predicate(a, i)) {
874
+ break
875
+ }
876
+ i++
877
+ }
878
+ return i
879
+ }
880
+
881
+ /**
882
+ * Split an `Iterable` into two parts:
883
+ *
884
+ * 1. the longest initial subarray for which all elements satisfy the specified predicate
885
+ * 2. the remaining elements
886
+ *
887
+ * @category splitting
888
+ * @since 2.0.0
889
+ */
890
+ export const span: {
891
+ <A, B extends A>(
892
+ refinement: (a: NoInfer<A>, i: number) => a is B
893
+ ): (self: Iterable<A>) => [init: Array<B>, rest: Array<Exclude<A, B>>]
894
+ <A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => [init: Array<A>, rest: Array<A>]
895
+ <A, B extends A>(
896
+ self: Iterable<A>,
897
+ refinement: (a: A, i: number) => a is B
898
+ ): [init: Array<B>, rest: Array<Exclude<A, B>>]
899
+ <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): [init: Array<A>, rest: Array<A>]
900
+ } = dual(
901
+ 2,
902
+ <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): [init: Array<A>, rest: Array<A>] =>
903
+ splitAt(self, spanIndex(self, predicate))
904
+ )
905
+
906
+ /**
907
+ * Drop a max number of elements from the start of an `Iterable`, creating a new `Array`.
908
+ *
909
+ * **Note**. `n` is normalized to a non negative integer.
910
+ *
911
+ * **Example**
912
+ *
913
+ * ```ts
914
+ * import { Array } from "effect"
915
+ *
916
+ * const result = Array.drop([1, 2, 3, 4, 5], 2)
917
+ * console.log(result) // [3, 4, 5]
918
+ * ```
919
+ *
920
+ * @category getters
921
+ * @since 2.0.0
922
+ */
923
+ export const drop: {
924
+ (n: number): <A>(self: Iterable<A>) => Array<A>
925
+ <A>(self: Iterable<A>, n: number): Array<A>
926
+ } = dual(2, <A>(self: Iterable<A>, n: number): Array<A> => {
927
+ const input = fromIterable(self)
928
+ return input.slice(clamp(n, input), input.length)
929
+ })
930
+
931
+ /**
932
+ * Drop a max number of elements from the end of an `Iterable`, creating a new `Array`.
933
+ *
934
+ * **Note**. `n` is normalized to a non negative integer.
935
+ *
936
+ * **Example**
937
+ *
938
+ * ```ts
939
+ * import { Array } from "effect"
940
+ *
941
+ * const result = Array.dropRight([1, 2, 3, 4, 5], 2)
942
+ * console.log(result) // [1, 2, 3]
943
+ * ```
944
+ *
945
+ * @category getters
946
+ * @since 2.0.0
947
+ */
948
+ export const dropRight: {
949
+ (n: number): <A>(self: Iterable<A>) => Array<A>
950
+ <A>(self: Iterable<A>, n: number): Array<A>
951
+ } = dual(2, <A>(self: Iterable<A>, n: number): Array<A> => {
952
+ const input = fromIterable(self)
953
+ return input.slice(0, input.length - clamp(n, input))
954
+ })
955
+
956
+ /**
957
+ * Remove the longest initial subarray for which all element satisfy the specified predicate, creating a new `Array`.
958
+ *
959
+ * **Example**
960
+ *
961
+ * ```ts
962
+ * import { Array } from "effect"
963
+ *
964
+ * const result = Array.dropWhile([1, 2, 3, 4, 5], x => x < 4)
965
+ * console.log(result) // [4, 5]
966
+ * ```
967
+ *
968
+ * @category getters
969
+ * @since 2.0.0
970
+ */
971
+ export const dropWhile: {
972
+ <A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Array<A>
973
+ <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Array<A>
974
+ } = dual(
975
+ 2,
976
+ <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Array<A> =>
977
+ fromIterable(self).slice(spanIndex(self, predicate))
978
+ )
979
+
980
+ /**
981
+ * Return the first index for which a predicate holds.
982
+ *
983
+ * **Example**
984
+ *
985
+ * ```ts
986
+ * import { Array } from "effect"
987
+ *
988
+ * const result = Array.findFirstIndex([5, 3, 8, 9], x => x > 5)
989
+ * console.log(result) // Option.some(2)
990
+ * ```
991
+ *
992
+ * @category elements
993
+ * @since 2.0.0
994
+ */
995
+ export const findFirstIndex: {
996
+ <A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Option.Option<number>
997
+ <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Option.Option<number>
998
+ } = dual(2, <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Option.Option<number> => {
999
+ let i = 0
1000
+ for (const a of self) {
1001
+ if (predicate(a, i)) {
1002
+ return Option.some(i)
1003
+ }
1004
+ i++
1005
+ }
1006
+ return Option.none()
1007
+ })
1008
+
1009
+ /**
1010
+ * Return the last index for which a predicate holds.
1011
+ *
1012
+ * **Example**
1013
+ *
1014
+ * ```ts
1015
+ * import { Array } from "effect"
1016
+ *
1017
+ * const result = Array.findLastIndex([1, 3, 8, 9], x => x < 5)
1018
+ * console.log(result) // Option.some(1)
1019
+ * ```
1020
+ *
1021
+ * @category elements
1022
+ * @since 2.0.0
1023
+ */
1024
+ export const findLastIndex: {
1025
+ <A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Option.Option<number>
1026
+ <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Option.Option<number>
1027
+ } = dual(2, <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Option.Option<number> => {
1028
+ const input = fromIterable(self)
1029
+ for (let i = input.length - 1; i >= 0; i--) {
1030
+ if (predicate(input[i], i)) {
1031
+ return Option.some(i)
1032
+ }
1033
+ }
1034
+ return Option.none()
1035
+ })
1036
+
1037
+ /**
1038
+ * Returns the first element that satisfies the specified
1039
+ * predicate, or `None` if no such element exists.
1040
+ *
1041
+ * **Example**
1042
+ *
1043
+ * ```ts
1044
+ * import { Array } from "effect"
1045
+ *
1046
+ * const result = Array.findFirst([1, 2, 3, 4, 5], x => x > 3)
1047
+ * console.log(result) // Option.some(4)
1048
+ * ```
1049
+ *
1050
+ * @category elements
1051
+ * @since 2.0.0
1052
+ */
1053
+ export const findFirst: {
1054
+ <A, B>(f: (a: NoInfer<A>, i: number) => Option.Option<B>): (self: Iterable<A>) => Option.Option<B>
1055
+ <A, B extends A>(refinement: (a: NoInfer<A>, i: number) => a is B): (self: Iterable<A>) => Option.Option<B>
1056
+ <A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Option.Option<A>
1057
+ <A, B>(self: Iterable<A>, f: (a: A, i: number) => Option.Option<B>): Option.Option<B>
1058
+ <A, B extends A>(self: Iterable<A>, refinement: (a: A, i: number) => a is B): Option.Option<B>
1059
+ <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Option.Option<A>
1060
+ } = moduleIterable.findFirst
1061
+
1062
+ /**
1063
+ * Finds the last element in an iterable collection that satisfies the given predicate or refinement.
1064
+ * Returns an `Option` containing the found element, or `Option.none` if no element matches.
1065
+ *
1066
+ * **Example**
1067
+ *
1068
+ * ```ts
1069
+ * import { Array } from "effect"
1070
+ *
1071
+ * const result = Array.findLast([1, 2, 3, 4, 5], n => n % 2 === 0)
1072
+ * console.log(result) // Option.some(4)
1073
+ * ```
1074
+ *
1075
+ * @category elements
1076
+ * @since 2.0.0
1077
+ */
1078
+ export const findLast: {
1079
+ <A, B>(f: (a: NoInfer<A>, i: number) => Option.Option<B>): (self: Iterable<A>) => Option.Option<B>
1080
+ <A, B extends A>(refinement: (a: NoInfer<A>, i: number) => a is B): (self: Iterable<A>) => Option.Option<B>
1081
+ <A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Option.Option<A>
1082
+ <A, B>(self: Iterable<A>, f: (a: A, i: number) => Option.Option<B>): Option.Option<B>
1083
+ <A, B extends A>(self: Iterable<A>, refinement: (a: A, i: number) => a is B): Option.Option<B>
1084
+ <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Option.Option<A>
1085
+ } = dual(
1086
+ 2,
1087
+ <A>(
1088
+ self: Iterable<A>,
1089
+ f: ((a: A, i: number) => boolean) | ((a: A, i: number) => Option.Option<A>)
1090
+ ): Option.Option<A> => {
1091
+ const input = fromIterable(self)
1092
+ for (let i = input.length - 1; i >= 0; i--) {
1093
+ const a = input[i]
1094
+ const o = f(a, i)
1095
+ if (Predicate.isBoolean(o)) {
1096
+ if (o) {
1097
+ return Option.some(a)
1098
+ }
1099
+ } else {
1100
+ if (Option.isSome(o)) {
1101
+ return o
1102
+ }
1103
+ }
1104
+ }
1105
+ return Option.none()
1106
+ }
1107
+ )
1108
+
1109
+ /**
1110
+ * Returns a tuple of the first element that satisfies the specified
1111
+ * predicate and its index, or `None` if no such element exists.
1112
+ *
1113
+ * **Example**
1114
+ *
1115
+ * ```ts
1116
+ * import { Array } from "effect"
1117
+ *
1118
+ * const result = Array.findFirstWithIndex([1, 2, 3, 4, 5], x => x > 3)
1119
+ * console.log(result) // Option.some([4, 3])
1120
+ * ```
1121
+ *
1122
+ * @category elements
1123
+ * @since 3.17.0
1124
+ */
1125
+ export const findFirstWithIndex: {
1126
+ <A, B>(f: (a: NoInfer<A>, i: number) => Option.Option<B>): (self: Iterable<A>) => Option.Option<[B, number]>
1127
+ <A, B extends A>(refinement: (a: NoInfer<A>, i: number) => a is B): (self: Iterable<A>) => Option.Option<[B, number]>
1128
+ <A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Option.Option<[A, number]>
1129
+ <A, B>(self: Iterable<A>, f: (a: A, i: number) => Option.Option<B>): Option.Option<[B, number]>
1130
+ <A, B extends A>(self: Iterable<A>, refinement: (a: A, i: number) => a is B): Option.Option<[B, number]>
1131
+ <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Option.Option<[A, number]>
1132
+ } = dual(
1133
+ 2,
1134
+ <A>(
1135
+ self: Iterable<A>,
1136
+ f: ((a: A, i: number) => boolean) | ((a: A, i: number) => Option.Option<A>)
1137
+ ): Option.Option<[A, number]> => {
1138
+ let i = 0
1139
+ for (const a of self) {
1140
+ const o = f(a, i)
1141
+ if (Predicate.isBoolean(o)) {
1142
+ if (o) {
1143
+ return Option.some([a, i])
1144
+ }
1145
+ } else {
1146
+ if (Option.isSome(o)) {
1147
+ return Option.some([o.value, i])
1148
+ }
1149
+ }
1150
+ i++
1151
+ }
1152
+ return Option.none()
1153
+ }
1154
+ )
1155
+
1156
+ /**
1157
+ * Counts all the element of the given array that pass the given predicate
1158
+ *
1159
+ * **Example**
1160
+ *
1161
+ * ```ts
1162
+ * import { Array } from "effect"
1163
+ *
1164
+ * const result = Array.countBy([1, 2, 3, 4, 5], n => n % 2 === 0)
1165
+ * console.log(result) // 2
1166
+ * ```
1167
+ *
1168
+ * @category folding
1169
+ * @since 3.16.0
1170
+ */
1171
+ export const countBy: {
1172
+ <A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => number
1173
+ <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): number
1174
+ } = dual(
1175
+ 2,
1176
+ <A>(
1177
+ self: Iterable<A>,
1178
+ f: (a: A, i: number) => boolean
1179
+ ): number => {
1180
+ let count = 0
1181
+ const as = fromIterable(self)
1182
+ for (let i = 0; i < as.length; i++) {
1183
+ const a = as[i]
1184
+ if (f(a, i)) {
1185
+ count++
1186
+ }
1187
+ }
1188
+ return count
1189
+ }
1190
+ )
1191
+
1192
+ /**
1193
+ * Insert an element at the specified index, creating a new `NonEmptyArray`,
1194
+ * or return `None` if the index is out of bounds.
1195
+ *
1196
+ * **Example**
1197
+ *
1198
+ * ```ts
1199
+ * import { Array } from "effect"
1200
+ *
1201
+ * const result = Array.insertAt(['a', 'b', 'c', 'e'], 3, 'd')
1202
+ * console.log(result) // Option.some(['a', 'b', 'c', 'd', 'e'])
1203
+ * ```
1204
+ *
1205
+ * @since 2.0.0
1206
+ */
1207
+ export const insertAt: {
1208
+ <B>(i: number, b: B): <A>(self: Iterable<A>) => Option.Option<NonEmptyArray<A | B>>
1209
+ <A, B>(self: Iterable<A>, i: number, b: B): Option.Option<NonEmptyArray<A | B>>
1210
+ } = dual(3, <A, B>(self: Iterable<A>, i: number, b: B): Option.Option<NonEmptyArray<A | B>> => {
1211
+ const out: Array<A | B> = Array.from(self)
1212
+ // v--- `= self.length` is ok, it means inserting in last position
1213
+ if (i < 0 || i > out.length) {
1214
+ return Option.none()
1215
+ }
1216
+ out.splice(i, 0, b)
1217
+ return Option.some(out) as any
1218
+ })
1219
+
1220
+ /**
1221
+ * Change the element at the specified index, creating a new `Array`,
1222
+ * or return a copy of the input if the index is out of bounds.
1223
+ *
1224
+ * **Example**
1225
+ *
1226
+ * ```ts
1227
+ * import { Array } from "effect"
1228
+ *
1229
+ * const result = Array.replace(['a', 'b', 'c', 'd'], 1, 'z')
1230
+ * console.log(result) // ['a', 'z', 'c', 'd']
1231
+ * ```
1232
+ *
1233
+ * @since 2.0.0
1234
+ */
1235
+ export const replace: {
1236
+ <B>(
1237
+ i: number,
1238
+ b: B
1239
+ ): <A, S extends Iterable<A> = Iterable<A>>(
1240
+ self: S
1241
+ ) => ReadonlyArray.With<S, ReadonlyArray.Infer<S> | B>
1242
+ <A, B, S extends Iterable<A> = Iterable<A>>(
1243
+ self: S,
1244
+ i: number,
1245
+ b: B
1246
+ ): ReadonlyArray.With<S, ReadonlyArray.Infer<S> | B>
1247
+ } = dual(3, <A, B>(self: Iterable<A>, i: number, b: B): Array<A | B> => modify(self, i, () => b))
1248
+
1249
+ /**
1250
+ * Replaces an element in an array with the given value, returning an option of the updated array.
1251
+ *
1252
+ * **Example**
1253
+ *
1254
+ * ```ts
1255
+ * import { Array } from "effect"
1256
+ *
1257
+ * const result = Array.replaceOption([1, 2, 3], 1, 4)
1258
+ * console.log(result) // Option.some([1, 4, 3])
1259
+ * ```
1260
+ *
1261
+ * @since 2.0.0
1262
+ */
1263
+ export const replaceOption: {
1264
+ <B>(
1265
+ i: number,
1266
+ b: B
1267
+ ): <A, S extends Iterable<A> = Iterable<A>>(
1268
+ self: S
1269
+ ) => Option.Option<ReadonlyArray.With<S, ReadonlyArray.Infer<S> | B>>
1270
+ <A, B, S extends Iterable<A> = Iterable<A>>(
1271
+ self: S,
1272
+ i: number,
1273
+ b: B
1274
+ ): Option.Option<ReadonlyArray.With<S, ReadonlyArray.Infer<S> | B>>
1275
+ } = dual(
1276
+ 3,
1277
+ <A, B>(self: Iterable<A>, i: number, b: B): Option.Option<Array<A | B>> => modifyOption(self, i, () => b)
1278
+ )
1279
+
1280
+ /**
1281
+ * Apply a function to the element at the specified index, creating a new `Array`,
1282
+ * or return a copy of the input if the index is out of bounds.
1283
+ *
1284
+ * **Example**
1285
+ *
1286
+ * ```ts
1287
+ * import { Array } from "effect"
1288
+ *
1289
+ * const result = Array.modify([1, 2, 3, 4], 2, (n) => n * 2)
1290
+ * console.log(result) // [1, 2, 6, 4]
1291
+ * ```
1292
+ *
1293
+ * @since 2.0.0
1294
+ */
1295
+ export const modify: {
1296
+ <A, B, S extends Iterable<A> = Iterable<A>>(
1297
+ i: number,
1298
+ f: (a: ReadonlyArray.Infer<S>) => B
1299
+ ): (self: S) => ReadonlyArray.With<S, ReadonlyArray.Infer<S> | B>
1300
+ <A, B, S extends Iterable<A> = Iterable<A>>(
1301
+ self: S,
1302
+ i: number,
1303
+ f: (a: ReadonlyArray.Infer<S>) => B
1304
+ ): ReadonlyArray.With<S, ReadonlyArray.Infer<S> | B>
1305
+ } = dual(
1306
+ 3,
1307
+ <A, B>(self: Iterable<A>, i: number, f: (a: A) => B): Array<A | B> => {
1308
+ const out: Array<A | B> = Array.from(self)
1309
+ if (isOutOfBounds(i, out)) {
1310
+ return out
1311
+ }
1312
+ const b = f(out[i] as A)
1313
+ out[i] = b
1314
+ return out
1315
+ }
1316
+ )
1317
+
1318
+ /**
1319
+ * Apply a function to the element at the specified index, creating a new `Array`,
1320
+ * or return `None` if the index is out of bounds.
1321
+ *
1322
+ * **Example**
1323
+ *
1324
+ * ```ts
1325
+ * import { Array } from "effect"
1326
+ *
1327
+ * const input = [1, 2, 3, 4]
1328
+ * const result = Array.modifyOption(input, 2, (n) => n * 2)
1329
+ * console.log(result) // Option.some([1, 2, 6, 4])
1330
+ *
1331
+ * const outOfBoundsResult = Array.modifyOption(input, 5, (n) => n * 2)
1332
+ * console.log(outOfBoundsResult) // Option.none()
1333
+ * ```
1334
+ *
1335
+ * @since 2.0.0
1336
+ */
1337
+ export const modifyOption: {
1338
+ <A, B, S extends Iterable<A> = Iterable<A>>(
1339
+ i: number,
1340
+ f: (a: ReadonlyArray.Infer<S>) => B
1341
+ ): (self: S) => Option.Option<ReadonlyArray.With<S, ReadonlyArray.Infer<S> | B>>
1342
+ <A, B, S extends Iterable<A> = Iterable<A>>(
1343
+ self: S,
1344
+ i: number,
1345
+ f: (a: ReadonlyArray.Infer<S>) => B
1346
+ ): Option.Option<ReadonlyArray.With<S, ReadonlyArray.Infer<S> | B>>
1347
+ } = dual(3, <A, B>(self: Iterable<A>, i: number, f: (a: A) => B): Option.Option<Array<A | B>> => {
1348
+ const arr = fromIterable(self)
1349
+ if (isOutOfBounds(i, arr)) {
1350
+ return Option.none()
1351
+ }
1352
+ const out: Array<A | B> = Array.isArray(self) ? self.slice() : arr
1353
+ const b = f(arr[i])
1354
+ out[i] = b
1355
+ return Option.some(out)
1356
+ })
1357
+
1358
+ /**
1359
+ * Delete the element at the specified index, creating a new `Array`,
1360
+ * or return a copy of the input if the index is out of bounds.
1361
+ *
1362
+ * **Example**
1363
+ *
1364
+ * ```ts
1365
+ * import { Array } from "effect"
1366
+ *
1367
+ * const input = [1, 2, 3, 4]
1368
+ * const result = Array.remove(input, 2)
1369
+ * console.log(result) // [1, 2, 4]
1370
+ *
1371
+ * const outOfBoundsResult = Array.remove(input, 5)
1372
+ * console.log(outOfBoundsResult) // [1, 2, 3, 4]
1373
+ * ```
1374
+ *
1375
+ * @since 2.0.0
1376
+ */
1377
+ export const remove: {
1378
+ (i: number): <A>(self: Iterable<A>) => Array<A>
1379
+ <A>(self: Iterable<A>, i: number): Array<A>
1380
+ } = dual(2, <A>(self: Iterable<A>, i: number): Array<A> => {
1381
+ const out = Array.from(self)
1382
+ if (isOutOfBounds(i, out)) {
1383
+ return out
1384
+ }
1385
+ out.splice(i, 1)
1386
+ return out
1387
+ })
1388
+
1389
+ /**
1390
+ * Delete the element at the specified index, creating a new `Array`,
1391
+ * or return `None` if the index is out of bounds.
1392
+ *
1393
+ * @example
1394
+ * ```ts
1395
+ * import * as assert from "node:assert"
1396
+ * import { Array, Option } from "effect"
1397
+ *
1398
+ * const numbers = [1, 2, 3, 4]
1399
+ * const result = Array.removeOption(numbers, 2)
1400
+ * assert.deepStrictEqual(result, Option.some([1, 2, 4]))
1401
+ *
1402
+ * const outOfBoundsResult = Array.removeOption(numbers, 5)
1403
+ * assert.deepStrictEqual(outOfBoundsResult, Option.none())
1404
+ * ```
1405
+ *
1406
+ * @since 3.16.0
1407
+ */
1408
+ export const removeOption: {
1409
+ (i: number): <A>(self: Iterable<A>) => Option.Option<Array<A>>
1410
+ <A>(self: Iterable<A>, i: number): Option.Option<Array<A>>
1411
+ } = dual(2, <A>(self: Iterable<A>, i: number): Option.Option<Array<A>> => {
1412
+ const arr = fromIterable(self)
1413
+ if (isOutOfBounds(i, arr)) {
1414
+ return Option.none()
1415
+ }
1416
+ const out = Array.isArray(self) ? self.slice() : arr
1417
+ out.splice(i, 1)
1418
+ return Option.some(out)
1419
+ })
1420
+
1421
+ /**
1422
+ * Reverse an `Iterable`, creating a new `Array`.
1423
+ *
1424
+ * **Example**
1425
+ *
1426
+ * ```ts
1427
+ * import { Array } from "effect"
1428
+ *
1429
+ * const result = Array.reverse([1, 2, 3, 4])
1430
+ * console.log(result) // [4, 3, 2, 1]
1431
+ * ```
1432
+ *
1433
+ * @category elements
1434
+ * @since 2.0.0
1435
+ */
1436
+ export const reverse = <S extends Iterable<any>>(
1437
+ self: S
1438
+ ): S extends NonEmptyReadonlyArray<infer A> ? NonEmptyArray<A> : S extends Iterable<infer A> ? Array<A> : never =>
1439
+ Array.from(self).reverse() as any
1440
+
1441
+ /**
1442
+ * Create a new array with elements sorted in increasing order based on the specified comparator.
1443
+ * If the input is a `NonEmptyReadonlyArray`, the output will also be a `NonEmptyReadonlyArray`.
1444
+ *
1445
+ * @category sorting
1446
+ * @since 2.0.0
1447
+ */
1448
+ export const sort: {
1449
+ <B>(
1450
+ O: Order.Order<B>
1451
+ ): <A extends B, S extends Iterable<A>>(self: S) => ReadonlyArray.With<S, ReadonlyArray.Infer<S>>
1452
+ <A extends B, B>(self: NonEmptyReadonlyArray<A>, O: Order.Order<B>): NonEmptyArray<A>
1453
+ <A extends B, B>(self: Iterable<A>, O: Order.Order<B>): Array<A>
1454
+ } = dual(2, <A extends B, B>(self: Iterable<A>, O: Order.Order<B>): Array<A> => {
1455
+ const out = Array.from(self)
1456
+ out.sort(O)
1457
+ return out
1458
+ })
1459
+
1460
+ /**
1461
+ * Sorts an array based on a provided mapping function and order. The mapping
1462
+ * function transforms the elements into a value that can be compared, and the
1463
+ * order defines how those values should be sorted.
1464
+ *
1465
+ * **Example**
1466
+ *
1467
+ * ```ts
1468
+ * import { Array, Order } from "effect"
1469
+ *
1470
+ * const result = Array.sortWith(["aaa", "b", "cc"], (s) => s.length, Order.number)
1471
+ * console.log(result) // ["b", "cc", "aaa"]
1472
+ *
1473
+ * // Explanation:
1474
+ * // The array of strings is sorted based on their lengths. The mapping function `(s) => s.length`
1475
+ * // converts each string into its length, and the `Order.number` specifies that the lengths should
1476
+ * // be sorted in ascending order.
1477
+ * ```
1478
+ *
1479
+ * @since 2.0.0
1480
+ * @category elements
1481
+ */
1482
+ export const sortWith: {
1483
+ <S extends Iterable<any>, B>(
1484
+ f: (a: ReadonlyArray.Infer<S>) => B,
1485
+ order: Order.Order<B>
1486
+ ): (self: S) => ReadonlyArray.With<S, ReadonlyArray.Infer<S>>
1487
+ <A, B>(self: NonEmptyReadonlyArray<A>, f: (a: A) => B, O: Order.Order<B>): NonEmptyArray<A>
1488
+ <A, B>(self: Iterable<A>, f: (a: A) => B, order: Order.Order<B>): Array<A>
1489
+ } = dual(
1490
+ 3,
1491
+ <A, B>(self: Iterable<A>, f: (a: A) => B, order: Order.Order<B>): Array<A> =>
1492
+ Array.from(self).map((a) => [a, f(a)] as const).sort(([, a], [, b]) => order(a, b)).map(([_]) => _)
1493
+ )
1494
+
1495
+ /**
1496
+ * Sorts the elements of an `Iterable` in increasing order based on the provided
1497
+ * orders. The elements are compared using the first order in `orders`, then the
1498
+ * second order if the first comparison is equal, and so on.
1499
+ *
1500
+ * **Example**
1501
+ *
1502
+ * ```ts
1503
+ * import { Array, Order, pipe } from "effect"
1504
+ *
1505
+ * const users = [
1506
+ * { name: "Alice", age: 30 },
1507
+ * { name: "Bob", age: 25 },
1508
+ * { name: "Charlie", age: 30 }
1509
+ * ]
1510
+ *
1511
+ * const result = pipe(
1512
+ * users,
1513
+ * Array.sortBy(
1514
+ * Order.mapInput(Order.number, (user: (typeof users)[number]) => user.age),
1515
+ * Order.mapInput(Order.string, (user: (typeof users)[number]) => user.name)
1516
+ * )
1517
+ * )
1518
+ *
1519
+ * console.log(result)
1520
+ * // [
1521
+ * // { name: "Bob", age: 25 },
1522
+ * // { name: "Alice", age: 30 },
1523
+ * // { name: "Charlie", age: 30 }
1524
+ * // ]
1525
+ *
1526
+ * // Explanation:
1527
+ * // The array of users is sorted first by age in ascending order. When ages are equal,
1528
+ * // the users are further sorted by name in ascending order.
1529
+ * ```
1530
+ *
1531
+ * @category sorting
1532
+ * @since 2.0.0
1533
+ */
1534
+ export const sortBy = <S extends Iterable<any>>(
1535
+ ...orders: ReadonlyArray<Order.Order<ReadonlyArray.Infer<S>>>
1536
+ ) => {
1537
+ const sortByAll = sort(Order.combineAll(orders))
1538
+ return (
1539
+ self: S
1540
+ ): S extends NonEmptyReadonlyArray<infer A> ? NonEmptyArray<A> : S extends Iterable<infer A> ? Array<A> : never => {
1541
+ const input = fromIterable(self)
1542
+ if (isNonEmptyReadonlyArray(input)) {
1543
+ return sortByAll(input) as any
1544
+ }
1545
+ return [] as any
1546
+ }
1547
+ }
1548
+
1549
+ /**
1550
+ * Takes two `Iterable`s and returns an `Array` of corresponding pairs.
1551
+ * If one input `Iterable` is short, excess elements of the
1552
+ * longer `Iterable` are discarded.
1553
+ *
1554
+ * **Example**
1555
+ *
1556
+ * ```ts
1557
+ * import { Array } from "effect"
1558
+ *
1559
+ * const result = Array.zip([1, 2, 3], ['a', 'b'])
1560
+ * console.log(result) // [[1, 'a'], [2, 'b']]
1561
+ * ```
1562
+ *
1563
+ * @category zipping
1564
+ * @since 2.0.0
1565
+ */
1566
+ export const zip: {
1567
+ <B>(that: NonEmptyReadonlyArray<B>): <A>(self: NonEmptyReadonlyArray<A>) => NonEmptyArray<[A, B]>
1568
+ <B>(that: Iterable<B>): <A>(self: Iterable<A>) => Array<[A, B]>
1569
+ <A, B>(self: NonEmptyReadonlyArray<A>, that: NonEmptyReadonlyArray<B>): NonEmptyArray<[A, B]>
1570
+ <A, B>(self: Iterable<A>, that: Iterable<B>): Array<[A, B]>
1571
+ } = dual(
1572
+ 2,
1573
+ <A, B>(self: Iterable<A>, that: Iterable<B>): Array<[A, B]> => zipWith(self, that, Tuple.make)
1574
+ )
1575
+
1576
+ /**
1577
+ * Apply a function to pairs of elements at the same index in two `Iterable`s, collecting the results in a new `Array`. If one
1578
+ * input `Iterable` is short, excess elements of the longer `Iterable` are discarded.
1579
+ *
1580
+ * **Example**
1581
+ *
1582
+ * ```ts
1583
+ * import { Array } from "effect"
1584
+ *
1585
+ * const result = Array.zipWith([1, 2, 3], [4, 5, 6], (a, b) => a + b)
1586
+ * console.log(result) // [5, 7, 9]
1587
+ * ```
1588
+ *
1589
+ * @category zipping
1590
+ * @since 2.0.0
1591
+ */
1592
+ export const zipWith: {
1593
+ <B, A, C>(that: NonEmptyReadonlyArray<B>, f: (a: A, b: B) => C): (self: NonEmptyReadonlyArray<A>) => NonEmptyArray<C>
1594
+ <B, A, C>(that: Iterable<B>, f: (a: A, b: B) => C): (self: Iterable<A>) => Array<C>
1595
+ <A, B, C>(self: NonEmptyReadonlyArray<A>, that: NonEmptyReadonlyArray<B>, f: (a: A, b: B) => C): NonEmptyArray<C>
1596
+ <B, A, C>(self: Iterable<A>, that: Iterable<B>, f: (a: A, b: B) => C): Array<C>
1597
+ } = dual(3, <B, A, C>(self: Iterable<A>, that: Iterable<B>, f: (a: A, b: B) => C): Array<C> => {
1598
+ const as = fromIterable(self)
1599
+ const bs = fromIterable(that)
1600
+ if (isNonEmptyReadonlyArray(as) && isNonEmptyReadonlyArray(bs)) {
1601
+ const out: NonEmptyArray<C> = [f(headNonEmpty(as), headNonEmpty(bs))]
1602
+ const len = Math.min(as.length, bs.length)
1603
+ for (let i = 1; i < len; i++) {
1604
+ out[i] = f(as[i], bs[i])
1605
+ }
1606
+ return out
1607
+ }
1608
+ return []
1609
+ })
1610
+
1611
+ /**
1612
+ * This function is the inverse of `zip`. Takes an `Iterable` of pairs and return two corresponding `Array`s.
1613
+ *
1614
+ * **Example**
1615
+ *
1616
+ * ```ts
1617
+ * import { Array } from "effect"
1618
+ *
1619
+ * const result = Array.unzip([[1, "a"], [2, "b"], [3, "c"]])
1620
+ * console.log(result) // [[1, 2, 3], ['a', 'b', 'c']]
1621
+ * ```
1622
+ *
1623
+ * @since 2.0.0
1624
+ */
1625
+ export const unzip: <S extends Iterable<readonly [any, any]>>(
1626
+ self: S
1627
+ ) => S extends NonEmptyReadonlyArray<readonly [infer A, infer B]> ? [NonEmptyArray<A>, NonEmptyArray<B>]
1628
+ : S extends Iterable<readonly [infer A, infer B]> ? [Array<A>, Array<B>]
1629
+ : never = (<A, B>(self: Iterable<readonly [A, B]>): [Array<A>, Array<B>] => {
1630
+ const input = fromIterable(self)
1631
+ if (isNonEmptyReadonlyArray(input)) {
1632
+ const fa: NonEmptyArray<A> = [input[0][0]]
1633
+ const fb: NonEmptyArray<B> = [input[0][1]]
1634
+ for (let i = 1; i < input.length; i++) {
1635
+ fa[i] = input[i][0]
1636
+ fb[i] = input[i][1]
1637
+ }
1638
+ return [fa, fb]
1639
+ }
1640
+ return [[], []]
1641
+ }) as any
1642
+
1643
+ /**
1644
+ * Places an element in between members of an `Iterable`.
1645
+ * If the input is a non-empty array, the result is also a non-empty array.
1646
+ *
1647
+ * **Example**
1648
+ *
1649
+ * ```ts
1650
+ * import { Array } from "effect"
1651
+ *
1652
+ * const result = Array.intersperse([1, 2, 3], 0)
1653
+ * console.log(result) // [1, 0, 2, 0, 3]
1654
+ * ```
1655
+ *
1656
+ * @since 2.0.0
1657
+ */
1658
+ export const intersperse: {
1659
+ <B>(
1660
+ middle: B
1661
+ ): <S extends Iterable<any>>(self: S) => ReadonlyArray.With<S, ReadonlyArray.Infer<S> | B>
1662
+ <A, B>(self: NonEmptyReadonlyArray<A>, middle: B): NonEmptyArray<A | B>
1663
+ <A, B>(self: Iterable<A>, middle: B): Array<A | B>
1664
+ } = dual(2, <A, B>(self: Iterable<A>, middle: B): Array<A | B> => {
1665
+ const input = fromIterable(self)
1666
+ if (isNonEmptyReadonlyArray(input)) {
1667
+ const out: NonEmptyArray<A | B> = [headNonEmpty(input)]
1668
+ const tail = tailNonEmpty(input)
1669
+ for (let i = 0; i < tail.length; i++) {
1670
+ if (i < tail.length) {
1671
+ out.push(middle)
1672
+ }
1673
+ out.push(tail[i])
1674
+ }
1675
+ return out
1676
+ }
1677
+ return []
1678
+ })
1679
+
1680
+ /**
1681
+ * Apply a function to the head, creating a new `NonEmptyReadonlyArray`.
1682
+ *
1683
+ * **Example**
1684
+ *
1685
+ * ```ts
1686
+ * import { Array } from "effect"
1687
+ *
1688
+ * const result = Array.modifyNonEmptyHead([1, 2, 3], n => n * 10)
1689
+ * console.log(result) // [10, 2, 3]
1690
+ * ```
1691
+ *
1692
+ * @since 2.0.0
1693
+ */
1694
+ export const modifyNonEmptyHead: {
1695
+ <A, B>(f: (a: A) => B): (self: NonEmptyReadonlyArray<A>) => NonEmptyArray<A | B>
1696
+ <A, B>(self: NonEmptyReadonlyArray<A>, f: (a: A) => B): NonEmptyArray<A | B>
1697
+ } = dual(
1698
+ 2,
1699
+ <A, B>(
1700
+ self: NonEmptyReadonlyArray<A>,
1701
+ f: (a: A) => B
1702
+ ): NonEmptyArray<A | B> => [f(headNonEmpty(self)), ...tailNonEmpty(self)]
1703
+ )
1704
+
1705
+ /**
1706
+ * Change the head, creating a new `NonEmptyReadonlyArray`.
1707
+ *
1708
+ * **Example**
1709
+ *
1710
+ * ```ts
1711
+ * import { Array } from "effect"
1712
+ *
1713
+ * const result = Array.setNonEmptyHead([1, 2, 3], 10)
1714
+ * console.log(result) // [10, 2, 3]
1715
+ * ```
1716
+ *
1717
+ * @since 2.0.0
1718
+ */
1719
+ export const setNonEmptyHead: {
1720
+ <B>(b: B): <A>(self: NonEmptyReadonlyArray<A>) => NonEmptyArray<A | B>
1721
+ <A, B>(self: NonEmptyReadonlyArray<A>, b: B): NonEmptyArray<A | B>
1722
+ } = dual(
1723
+ 2,
1724
+ <A, B>(self: NonEmptyReadonlyArray<A>, b: B): NonEmptyArray<A | B> => modifyNonEmptyHead(self, () => b)
1725
+ )
1726
+
1727
+ /**
1728
+ * Apply a function to the last element, creating a new `NonEmptyReadonlyArray`.
1729
+ *
1730
+ * **Example**
1731
+ *
1732
+ * ```ts
1733
+ * import { Array } from "effect"
1734
+ *
1735
+ * const result = Array.modifyNonEmptyLast([1, 2, 3], n => n * 2)
1736
+ * console.log(result) // [1, 2, 6]
1737
+ * ```
1738
+ *
1739
+ * @since 2.0.0
1740
+ */
1741
+ export const modifyNonEmptyLast: {
1742
+ <A, B>(f: (a: A) => B): (self: NonEmptyReadonlyArray<A>) => NonEmptyArray<A | B>
1743
+ <A, B>(self: NonEmptyReadonlyArray<A>, f: (a: A) => B): NonEmptyArray<A | B>
1744
+ } = dual(
1745
+ 2,
1746
+ <A, B>(self: NonEmptyReadonlyArray<A>, f: (a: A) => B): NonEmptyArray<A | B> =>
1747
+ append(initNonEmpty(self), f(lastNonEmpty(self)))
1748
+ )
1749
+
1750
+ /**
1751
+ * Change the last element, creating a new `NonEmptyReadonlyArray`.
1752
+ *
1753
+ * **Example**
1754
+ *
1755
+ * ```ts
1756
+ * import { Array } from "effect"
1757
+ *
1758
+ * const result = Array.setNonEmptyLast([1, 2, 3], 4)
1759
+ * console.log(result) // [1, 2, 4]
1760
+ * ```
1761
+ *
1762
+ * @since 2.0.0
1763
+ */
1764
+ export const setNonEmptyLast: {
1765
+ <B>(b: B): <A>(self: NonEmptyReadonlyArray<A>) => NonEmptyArray<A | B>
1766
+ <A, B>(self: NonEmptyReadonlyArray<A>, b: B): NonEmptyArray<A | B>
1767
+ } = dual(
1768
+ 2,
1769
+ <A, B>(self: NonEmptyReadonlyArray<A>, b: B): NonEmptyArray<A | B> => modifyNonEmptyLast(self, () => b)
1770
+ )
1771
+
1772
+ /**
1773
+ * Rotate an `Iterable` by `n` steps.
1774
+ * If the input is a non-empty array, the result is also a non-empty array.
1775
+ *
1776
+ * **Example**
1777
+ *
1778
+ * ```ts
1779
+ * import { Array } from "effect"
1780
+ *
1781
+ * const result = Array.rotate(['a', 'b', 'c', 'd', 'e'], 2)
1782
+ * console.log(result) // [ 'd', 'e', 'a', 'b', 'c' ]
1783
+ * ```
1784
+ *
1785
+ * @since 2.0.0
1786
+ */
1787
+ export const rotate: {
1788
+ (n: number): <S extends Iterable<any>>(self: S) => ReadonlyArray.With<S, ReadonlyArray.Infer<S>>
1789
+ <A>(self: NonEmptyReadonlyArray<A>, n: number): NonEmptyArray<A>
1790
+ <A>(self: Iterable<A>, n: number): Array<A>
1791
+ } = dual(2, <A>(self: Iterable<A>, n: number): Array<A> => {
1792
+ const input = fromIterable(self)
1793
+ if (isNonEmptyReadonlyArray(input)) {
1794
+ const len = input.length
1795
+ const m = Math.round(n) % len
1796
+ if (isOutOfBounds(Math.abs(m), input) || m === 0) {
1797
+ return copy(input)
1798
+ }
1799
+ if (m < 0) {
1800
+ const [f, s] = splitNonEmptyAt(input, -m)
1801
+ return appendAll(s, f)
1802
+ } else {
1803
+ return rotate(self, m - len)
1804
+ }
1805
+ }
1806
+ return []
1807
+ })
1808
+
1809
+ /**
1810
+ * Returns a function that checks if a `ReadonlyArray` contains a given value using a provided `isEquivalent` function.
1811
+ *
1812
+ * **Example**
1813
+ *
1814
+ * ```ts
1815
+ * import { Array, pipe } from "effect"
1816
+ *
1817
+ * const isEquivalent = (a: number, b: number) => a === b
1818
+ * const containsNumber = Array.containsWith(isEquivalent)
1819
+ * const result = pipe([1, 2, 3, 4], containsNumber(3))
1820
+ * console.log(result) // true
1821
+ * ```
1822
+ *
1823
+ * @category elements
1824
+ * @since 2.0.0
1825
+ */
1826
+ export const containsWith = <A>(isEquivalent: (self: A, that: A) => boolean): {
1827
+ (a: A): (self: Iterable<A>) => boolean
1828
+ (self: Iterable<A>, a: A): boolean
1829
+ } =>
1830
+ dual(2, (self: Iterable<A>, a: A): boolean => {
1831
+ for (const i of self) {
1832
+ if (isEquivalent(a, i)) {
1833
+ return true
1834
+ }
1835
+ }
1836
+ return false
1837
+ })
1838
+
1839
+ const _equivalence = Equal.equivalence()
1840
+
1841
+ /**
1842
+ * Returns a function that checks if a `ReadonlyArray` contains a given value using the default `Equivalence`.
1843
+ *
1844
+ * **Example**
1845
+ *
1846
+ * ```ts
1847
+ * import { Array, pipe } from "effect"
1848
+ *
1849
+ * const result = pipe(['a', 'b', 'c', 'd'], Array.contains('c'))
1850
+ * console.log(result) // true
1851
+ * ```
1852
+ *
1853
+ * @category elements
1854
+ * @since 2.0.0
1855
+ */
1856
+ export const contains: {
1857
+ <A>(a: A): (self: Iterable<A>) => boolean
1858
+ <A>(self: Iterable<A>, a: A): boolean
1859
+ } = containsWith(_equivalence)
1860
+
1861
+ /**
1862
+ * A useful recursion pattern for processing an `Iterable` to produce a new `Array`, often used for "chopping" up the input
1863
+ * `Iterable`. Typically chop is called with some function that will consume an initial prefix of the `Iterable` and produce a
1864
+ * value and the rest of the `Array`.
1865
+ *
1866
+ * **Example**
1867
+ *
1868
+ * ```ts
1869
+ * import { Array } from "effect"
1870
+ *
1871
+ * const result = Array.chop([1, 2, 3, 4, 5], (as): [number, Array<number>] => [as[0] * 2, as.slice(1)])
1872
+ * console.log(result) // [2, 4, 6, 8, 10]
1873
+ *
1874
+ * // Explanation:
1875
+ * // The `chopFunction` takes the first element of the array, doubles it, and then returns it along with the rest of the array.
1876
+ * // The `chop` function applies this `chopFunction` recursively to the input array `[1, 2, 3, 4, 5]`,
1877
+ * // resulting in a new array `[2, 4, 6, 8, 10]`.
1878
+ * ```
1879
+ *
1880
+ * @since 2.0.0
1881
+ */
1882
+ export const chop: {
1883
+ <S extends Iterable<any>, B>(
1884
+ f: (as: NonEmptyReadonlyArray<ReadonlyArray.Infer<S>>) => readonly [B, ReadonlyArray<ReadonlyArray.Infer<S>>]
1885
+ ): (self: S) => ReadonlyArray.With<S, ReadonlyArray.Infer<S>>
1886
+ <A, B>(
1887
+ self: NonEmptyReadonlyArray<A>,
1888
+ f: (as: NonEmptyReadonlyArray<A>) => readonly [B, ReadonlyArray<A>]
1889
+ ): NonEmptyArray<B>
1890
+ <A, B>(
1891
+ self: Iterable<A>,
1892
+ f: (as: NonEmptyReadonlyArray<A>) => readonly [B, ReadonlyArray<A>]
1893
+ ): Array<B>
1894
+ } = dual(2, <A, B>(
1895
+ self: Iterable<A>,
1896
+ f: (as: NonEmptyReadonlyArray<A>) => readonly [B, ReadonlyArray<A>]
1897
+ ): Array<B> => {
1898
+ const input = fromIterable(self)
1899
+ if (isNonEmptyReadonlyArray(input)) {
1900
+ const [b, rest] = f(input)
1901
+ const out: NonEmptyArray<B> = [b]
1902
+ let next: ReadonlyArray<A> = rest
1903
+ while (internalArray.isNonEmptyArray(next)) {
1904
+ const [b, rest] = f(next)
1905
+ out.push(b)
1906
+ next = rest
1907
+ }
1908
+ return out
1909
+ }
1910
+ return []
1911
+ })
1912
+
1913
+ /**
1914
+ * Splits an `Iterable` into two segments, with the first segment containing a maximum of `n` elements.
1915
+ * The value of `n` can be `0`.
1916
+ *
1917
+ * **Example**
1918
+ *
1919
+ * ```ts
1920
+ * import { Array } from "effect"
1921
+ *
1922
+ * const result = Array.splitAt([1, 2, 3, 4, 5], 3)
1923
+ * console.log(result) // [[1, 2, 3], [4, 5]]
1924
+ * ```
1925
+ *
1926
+ * @category splitting
1927
+ * @since 2.0.0
1928
+ */
1929
+ export const splitAt: {
1930
+ (n: number): <A>(self: Iterable<A>) => [beforeIndex: Array<A>, fromIndex: Array<A>]
1931
+ <A>(self: Iterable<A>, n: number): [beforeIndex: Array<A>, fromIndex: Array<A>]
1932
+ } = dual(2, <A>(self: Iterable<A>, n: number): [Array<A>, Array<A>] => {
1933
+ const input = Array.from(self)
1934
+ const _n = Math.floor(n)
1935
+ if (isNonEmptyReadonlyArray(input)) {
1936
+ if (_n >= 1) {
1937
+ return splitNonEmptyAt(input, _n)
1938
+ }
1939
+ return [[], input]
1940
+ }
1941
+ return [input, []]
1942
+ })
1943
+
1944
+ /**
1945
+ * Splits a `NonEmptyReadonlyArray` into two segments, with the first segment containing a maximum of `n` elements.
1946
+ * The value of `n` must be `>= 1`.
1947
+ *
1948
+ * **Example**
1949
+ *
1950
+ * ```ts
1951
+ * import { Array } from "effect"
1952
+ *
1953
+ * const result = Array.splitNonEmptyAt(["a", "b", "c", "d", "e"], 3)
1954
+ * console.log(result) // [["a", "b", "c"], ["d", "e"]]
1955
+ * ```
1956
+ *
1957
+ * @category splitting
1958
+ * @since 2.0.0
1959
+ */
1960
+ export const splitNonEmptyAt: {
1961
+ (n: number): <A>(self: NonEmptyReadonlyArray<A>) => [beforeIndex: NonEmptyArray<A>, fromIndex: Array<A>]
1962
+ <A>(self: NonEmptyReadonlyArray<A>, n: number): [beforeIndex: NonEmptyArray<A>, fromIndex: Array<A>]
1963
+ } = dual(2, <A>(self: NonEmptyReadonlyArray<A>, n: number): [NonEmptyArray<A>, Array<A>] => {
1964
+ const _n = Math.max(1, Math.floor(n))
1965
+ return _n >= self.length ?
1966
+ [copy(self), []] :
1967
+ [prepend(self.slice(1, _n), headNonEmpty(self)), self.slice(_n)]
1968
+ })
1969
+
1970
+ /**
1971
+ * Splits this iterable into `n` equally sized arrays.
1972
+ *
1973
+ * **Example**
1974
+ *
1975
+ * ```ts
1976
+ * import { Array } from "effect"
1977
+ *
1978
+ * const result = Array.split([1, 2, 3, 4, 5, 6, 7, 8], 3)
1979
+ * console.log(result) // [[1, 2, 3], [4, 5, 6], [7, 8]]
1980
+ * ```
1981
+ *
1982
+ * @since 2.0.0
1983
+ * @category splitting
1984
+ */
1985
+ export const split: {
1986
+ (n: number): <A>(self: Iterable<A>) => Array<Array<A>>
1987
+ <A>(self: Iterable<A>, n: number): Array<Array<A>>
1988
+ } = dual(2, <A>(self: Iterable<A>, n: number) => {
1989
+ const input = fromIterable(self)
1990
+ return chunksOf(input, Math.ceil(input.length / Math.floor(n)))
1991
+ })
1992
+
1993
+ /**
1994
+ * Splits this iterable on the first element that matches this predicate.
1995
+ * Returns a tuple containing two arrays: the first one is before the match, and the second one is from the match onward.
1996
+ *
1997
+ * **Example**
1998
+ *
1999
+ * ```ts
2000
+ * import { Array } from "effect"
2001
+ *
2002
+ * const result = Array.splitWhere([1, 2, 3, 4, 5], n => n > 3)
2003
+ * console.log(result) // [[1, 2, 3], [4, 5]]
2004
+ * ```
2005
+ *
2006
+ * @category splitting
2007
+ * @since 2.0.0
2008
+ */
2009
+ export const splitWhere: {
2010
+ <A>(
2011
+ predicate: (a: NoInfer<A>, i: number) => boolean
2012
+ ): (self: Iterable<A>) => [beforeMatch: Array<A>, fromMatch: Array<A>]
2013
+ <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): [beforeMatch: Array<A>, fromMatch: Array<A>]
2014
+ } = dual(
2015
+ 2,
2016
+ <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): [beforeMatch: Array<A>, fromMatch: Array<A>] =>
2017
+ span(self, (a: A, i: number) => !predicate(a, i))
2018
+ )
2019
+
2020
+ /**
2021
+ * Copies an array.
2022
+ *
2023
+ * **Example**
2024
+ *
2025
+ * ```ts
2026
+ * import { Array } from "effect"
2027
+ *
2028
+ * const result = Array.copy([1, 2, 3])
2029
+ * console.log(result) // [1, 2, 3]
2030
+ * ```
2031
+ *
2032
+ * @since 2.0.0
2033
+ */
2034
+ export const copy: {
2035
+ <A>(self: NonEmptyReadonlyArray<A>): NonEmptyArray<A>
2036
+ <A>(self: ReadonlyArray<A>): Array<A>
2037
+ } = (<A>(self: ReadonlyArray<A>): Array<A> => self.slice()) as any
2038
+
2039
+ /**
2040
+ * Pads an array.
2041
+ * Returns a new array of length `n` with the elements of `array` followed by `fill` elements if `array` is shorter than `n`.
2042
+ * If `array` is longer than `n`, the returned array will be a slice of `array` containing the `n` first elements of `array`.
2043
+ * If `n` is less than or equal to 0, the returned array will be an empty array.
2044
+ *
2045
+ * **Example**
2046
+ *
2047
+ * ```ts
2048
+ * import { Array } from "effect"
2049
+ *
2050
+ * const result = Array.pad([1, 2, 3], 6, 0)
2051
+ * console.log(result) // [1, 2, 3, 0, 0, 0]
2052
+ * ```
2053
+ *
2054
+ * @since 3.8.4
2055
+ */
2056
+ export const pad: {
2057
+ <A, T>(
2058
+ n: number,
2059
+ fill: T
2060
+ ): (
2061
+ self: Array<A>
2062
+ ) => Array<A | T>
2063
+ <A, T>(self: Array<A>, n: number, fill: T): Array<A | T>
2064
+ } = dual(3, <A, T>(self: Array<A>, n: number, fill: T): Array<A | T> => {
2065
+ if (self.length >= n) {
2066
+ return take(self, n)
2067
+ }
2068
+ return appendAll(
2069
+ self,
2070
+ makeBy(n - self.length, () => fill)
2071
+ )
2072
+ })
2073
+
2074
+ /**
2075
+ * Splits an `Iterable` into length-`n` pieces. The last piece will be shorter if `n` does not evenly divide the length of
2076
+ * the `Iterable`. Note that `chunksOf(n)([])` is `[]`, not `[[]]`. This is intentional, and is consistent with a recursive
2077
+ * definition of `chunksOf`; it satisfies the property that
2078
+ *
2079
+ * ```ts skip-type-checking
2080
+ * chunksOf(n)(xs).concat(chunksOf(n)(ys)) == chunksOf(n)(xs.concat(ys)))
2081
+ * ```
2082
+ *
2083
+ * whenever `n` evenly divides the length of `self`.
2084
+ *
2085
+ * **Example**
2086
+ *
2087
+ * ```ts
2088
+ * import { Array } from "effect"
2089
+ *
2090
+ * const result = Array.chunksOf([1, 2, 3, 4, 5], 2)
2091
+ * console.log(result) // [[1, 2], [3, 4], [5]]
2092
+ *
2093
+ * // Explanation:
2094
+ * // The `chunksOf` function takes an array of numbers `[1, 2, 3, 4, 5]` and a number `2`.
2095
+ * // It splits the array into chunks of length 2. Since the array length is not evenly divisible by 2,
2096
+ * // the last chunk contains the remaining elements.
2097
+ * // The result is `[[1, 2], [3, 4], [5]]`.
2098
+ * ```
2099
+ *
2100
+ * @category splitting
2101
+ * @since 2.0.0
2102
+ */
2103
+ export const chunksOf: {
2104
+ (
2105
+ n: number
2106
+ ): <S extends Iterable<any>>(
2107
+ self: S
2108
+ ) => ReadonlyArray.With<S, NonEmptyArray<ReadonlyArray.Infer<S>>>
2109
+ <A>(self: NonEmptyReadonlyArray<A>, n: number): NonEmptyArray<NonEmptyArray<A>>
2110
+ <A>(self: Iterable<A>, n: number): Array<NonEmptyArray<A>>
2111
+ } = dual(2, <A>(self: Iterable<A>, n: number): Array<NonEmptyArray<A>> => {
2112
+ const input = fromIterable(self)
2113
+ if (isNonEmptyReadonlyArray(input)) {
2114
+ return chop(input, splitNonEmptyAt(n))
2115
+ }
2116
+ return []
2117
+ })
2118
+
2119
+ /**
2120
+ * Creates sliding windows of size `n` from an `Iterable`.
2121
+ * If the number of elements is less than `n` or if `n` is not greater than zero,
2122
+ * an empty array is returned.
2123
+ *
2124
+ * @example
2125
+ * ```ts
2126
+ * import * as assert from "node:assert"
2127
+ * import { Array } from "effect"
2128
+ *
2129
+ * const numbers = [1, 2, 3, 4, 5]
2130
+ * assert.deepStrictEqual(Array.window(numbers, 3), [[1, 2, 3], [2, 3, 4], [3, 4, 5]])
2131
+ * assert.deepStrictEqual(Array.window(numbers, 6), [])
2132
+ * ```
2133
+ *
2134
+ * @category splitting
2135
+ * @since 3.13.2
2136
+ */
2137
+ export const window: {
2138
+ <N extends number = number>(
2139
+ n: N
2140
+ ): <A>(self: Iterable<A>) => Array<TupleOf<N, A>>
2141
+ <A, N extends number = number>(
2142
+ self: Iterable<A>,
2143
+ n: N
2144
+ ): Array<TupleOf<N, A>>
2145
+ } = dual(2, <A, const N extends number>(self: Iterable<A>, n: N): Array<Array<A>> => {
2146
+ const input = fromIterable(self)
2147
+ if (n > 0 && isNonEmptyReadonlyArray(input)) {
2148
+ return Array.from(
2149
+ { length: input.length - (n - 1) },
2150
+ (_, index) => input.slice(index, index + n)
2151
+ )
2152
+ }
2153
+ return []
2154
+ })
2155
+
2156
+ /**
2157
+ * Group equal, consecutive elements of a `NonEmptyReadonlyArray` into `NonEmptyArray`s using the provided `isEquivalent` function.
2158
+ *
2159
+ * **Example**
2160
+ *
2161
+ * ```ts
2162
+ * import { Array } from "effect"
2163
+ *
2164
+ * const result = Array.groupWith(["a", "a", "b", "b", "b", "c", "a"], (x, y) => x === y)
2165
+ * console.log(result) // [["a", "a"], ["b", "b", "b"], ["c"], ["a"]]
2166
+ * ```
2167
+ *
2168
+ * @category grouping
2169
+ * @since 2.0.0
2170
+ */
2171
+ export const groupWith: {
2172
+ <A>(isEquivalent: (self: A, that: A) => boolean): (self: NonEmptyReadonlyArray<A>) => NonEmptyArray<NonEmptyArray<A>>
2173
+ <A>(self: NonEmptyReadonlyArray<A>, isEquivalent: (self: A, that: A) => boolean): NonEmptyArray<NonEmptyArray<A>>
2174
+ } = dual(
2175
+ 2,
2176
+ <A>(self: NonEmptyReadonlyArray<A>, isEquivalent: (self: A, that: A) => boolean): NonEmptyArray<NonEmptyArray<A>> =>
2177
+ chop(self, (as) => {
2178
+ const h = headNonEmpty(as)
2179
+ const out: NonEmptyArray<A> = [h]
2180
+ let i = 1
2181
+ for (; i < as.length; i++) {
2182
+ const a = as[i]
2183
+ if (isEquivalent(a, h)) {
2184
+ out.push(a)
2185
+ } else {
2186
+ break
2187
+ }
2188
+ }
2189
+ return [out, as.slice(i)]
2190
+ })
2191
+ )
2192
+
2193
+ /**
2194
+ * Group equal, consecutive elements of a `NonEmptyReadonlyArray` into `NonEmptyArray`s.
2195
+ *
2196
+ * **Example**
2197
+ *
2198
+ * ```ts
2199
+ * import { Array } from "effect"
2200
+ *
2201
+ * const result = Array.group([1, 1, 2, 2, 2, 3, 1])
2202
+ * console.log(result) // [[1, 1], [2, 2, 2], [3], [1]]
2203
+ * ```
2204
+ *
2205
+ * @category grouping
2206
+ * @since 2.0.0
2207
+ */
2208
+ export const group: <A>(self: NonEmptyReadonlyArray<A>) => NonEmptyArray<NonEmptyArray<A>> = groupWith(
2209
+ Equal.equivalence()
2210
+ )
2211
+
2212
+ /**
2213
+ * Splits an `Iterable` into sub-non-empty-arrays stored in an object, based on the result of calling a `string`-returning
2214
+ * function on each element, and grouping the results according to values returned
2215
+ *
2216
+ * **Example**
2217
+ *
2218
+ * ```ts
2219
+ * import { Array } from "effect"
2220
+ *
2221
+ * const people = [
2222
+ * { name: "Alice", group: "A" },
2223
+ * { name: "Bob", group: "B" },
2224
+ * { name: "Charlie", group: "A" }
2225
+ * ]
2226
+ *
2227
+ * const result = Array.groupBy(people, person => person.group)
2228
+ * console.log(result)
2229
+ * // {
2230
+ * // A: [{ name: "Alice", group: "A" }, { name: "Charlie", group: "A" }],
2231
+ * // B: [{ name: "Bob", group: "B" }]
2232
+ * // }
2233
+ * ```
2234
+ *
2235
+ * @category grouping
2236
+ * @since 2.0.0
2237
+ */
2238
+ export const groupBy: {
2239
+ <A, K extends string | symbol>(
2240
+ f: (a: A) => K
2241
+ ): (self: Iterable<A>) => Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>
2242
+ <A, K extends string | symbol>(
2243
+ self: Iterable<A>,
2244
+ f: (a: A) => K
2245
+ ): Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>
2246
+ } = dual(2, <A, K extends string | symbol>(
2247
+ self: Iterable<A>,
2248
+ f: (a: A) => K
2249
+ ): Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>> => {
2250
+ const out: Record<string | symbol, NonEmptyArray<A>> = {}
2251
+ for (const a of self) {
2252
+ const k = f(a)
2253
+ if (Object.prototype.hasOwnProperty.call(out, k)) {
2254
+ out[k].push(a)
2255
+ } else {
2256
+ out[k] = [a]
2257
+ }
2258
+ }
2259
+ return out
2260
+ })
2261
+
2262
+ /**
2263
+ * Calculates the union of two arrays using the provided equivalence relation.
2264
+ *
2265
+ * **Example**
2266
+ *
2267
+ * ```ts
2268
+ * import { Array } from "effect"
2269
+ *
2270
+ * const union = Array.unionWith([1, 2], [2, 3], (a, b) => a === b)
2271
+ * console.log(union) // [1, 2, 3]
2272
+ * ```
2273
+ *
2274
+ * @since 2.0.0
2275
+ */
2276
+ export const unionWith: {
2277
+ <S extends Iterable<any>, T extends Iterable<any>>(
2278
+ that: T,
2279
+ isEquivalent: (self: ReadonlyArray.Infer<S>, that: ReadonlyArray.Infer<T>) => boolean
2280
+ ): (self: S) => ReadonlyArray.OrNonEmpty<S, T, ReadonlyArray.Infer<S> | ReadonlyArray.Infer<T>>
2281
+ <A, B>(
2282
+ self: NonEmptyReadonlyArray<A>,
2283
+ that: Iterable<B>,
2284
+ isEquivalent: (self: A, that: B) => boolean
2285
+ ): NonEmptyArray<A | B>
2286
+ <A, B>(
2287
+ self: Iterable<A>,
2288
+ that: NonEmptyReadonlyArray<B>,
2289
+ isEquivalent: (self: A, that: B) => boolean
2290
+ ): NonEmptyArray<A | B>
2291
+ <A, B>(self: Iterable<A>, that: Iterable<B>, isEquivalent: (self: A, that: B) => boolean): Array<A | B>
2292
+ } = dual(3, <A>(self: Iterable<A>, that: Iterable<A>, isEquivalent: (self: A, that: A) => boolean): Array<A> => {
2293
+ const a = fromIterable(self)
2294
+ const b = fromIterable(that)
2295
+ if (isNonEmptyReadonlyArray(a)) {
2296
+ if (isNonEmptyReadonlyArray(b)) {
2297
+ const dedupe = dedupeWith(isEquivalent)
2298
+ return dedupe(appendAll(a, b))
2299
+ }
2300
+ return a
2301
+ }
2302
+ return b
2303
+ })
2304
+
2305
+ /**
2306
+ * Creates a union of two arrays, removing duplicates.
2307
+ *
2308
+ * **Example**
2309
+ *
2310
+ * ```ts
2311
+ * import { Array } from "effect"
2312
+ *
2313
+ * const result = Array.union([1, 2], [2, 3])
2314
+ * console.log(result) // [1, 2, 3]
2315
+ * ```
2316
+ *
2317
+ * @since 2.0.0
2318
+ */
2319
+ export const union: {
2320
+ <T extends Iterable<any>>(
2321
+ that: T
2322
+ ): <S extends Iterable<any>>(
2323
+ self: S
2324
+ ) => ReadonlyArray.OrNonEmpty<S, T, ReadonlyArray.Infer<S> | ReadonlyArray.Infer<T>>
2325
+ <A, B>(self: NonEmptyReadonlyArray<A>, that: ReadonlyArray<B>): NonEmptyArray<A | B>
2326
+ <A, B>(self: ReadonlyArray<A>, that: NonEmptyReadonlyArray<B>): NonEmptyArray<A | B>
2327
+ <A, B>(self: Iterable<A>, that: Iterable<B>): Array<A | B>
2328
+ } = dual(2, <A, B>(self: Iterable<A>, that: Iterable<B>): Array<A | B> => unionWith(self, that, _equivalence))
2329
+
2330
+ /**
2331
+ * Creates an `Array` of unique values that are included in all given `Iterable`s using the provided `isEquivalent` function.
2332
+ * The order and references of result values are determined by the first `Iterable`.
2333
+ *
2334
+ * **Example**
2335
+ *
2336
+ * ```ts
2337
+ * import { Array } from "effect"
2338
+ *
2339
+ * const array1 = [{ id: 1 }, { id: 2 }, { id: 3 }]
2340
+ * const array2 = [{ id: 3 }, { id: 4 }, { id: 1 }]
2341
+ * const isEquivalent = (a: { id: number }, b: { id: number }) => a.id === b.id
2342
+ * const result = Array.intersectionWith(isEquivalent)(array2)(array1)
2343
+ * console.log(result) // [{ id: 1 }, { id: 3 }]
2344
+ * ```
2345
+ *
2346
+ * @since 2.0.0
2347
+ */
2348
+ export const intersectionWith = <A>(isEquivalent: (self: A, that: A) => boolean): {
2349
+ (that: Iterable<A>): (self: Iterable<A>) => Array<A>
2350
+ (self: Iterable<A>, that: Iterable<A>): Array<A>
2351
+ } => {
2352
+ const has = containsWith(isEquivalent)
2353
+ return dual(
2354
+ 2,
2355
+ (self: Iterable<A>, that: Iterable<A>): Array<A> => {
2356
+ const bs = fromIterable(that)
2357
+ return fromIterable(self).filter((a) => has(bs, a))
2358
+ }
2359
+ )
2360
+ }
2361
+
2362
+ /**
2363
+ * Creates an `Array` of unique values that are included in all given `Iterable`s.
2364
+ * The order and references of result values are determined by the first `Iterable`.
2365
+ *
2366
+ * **Example**
2367
+ *
2368
+ * ```ts
2369
+ * import { Array } from "effect"
2370
+ *
2371
+ * const result = Array.intersection([1, 2, 3], [3, 4, 1])
2372
+ * console.log(result) // [1, 3]
2373
+ * ```
2374
+ *
2375
+ * @since 2.0.0
2376
+ */
2377
+ export const intersection: {
2378
+ <B>(that: Iterable<B>): <A>(self: Iterable<A>) => Array<A & B>
2379
+ <A, B>(self: Iterable<A>, that: Iterable<B>): Array<A & B>
2380
+ } = intersectionWith(_equivalence)
2381
+
2382
+ /**
2383
+ * Creates a `Array` of values not included in the other given `Iterable` using the provided `isEquivalent` function.
2384
+ * The order and references of result values are determined by the first `Iterable`.
2385
+ *
2386
+ * **Example**
2387
+ *
2388
+ * ```ts
2389
+ * import { Array } from "effect"
2390
+ *
2391
+ * const array1 = [1, 2, 3]
2392
+ * const array2 = [2, 3, 4]
2393
+ * const difference = Array.differenceWith<number>((a, b) => a === b)(array1, array2)
2394
+ * console.log(difference) // [1]
2395
+ * ```
2396
+ *
2397
+ * @since 2.0.0
2398
+ */
2399
+ export const differenceWith = <A>(isEquivalent: (self: A, that: A) => boolean): {
2400
+ (that: Iterable<A>): (self: Iterable<A>) => Array<A>
2401
+ (self: Iterable<A>, that: Iterable<A>): Array<A>
2402
+ } => {
2403
+ const has = containsWith(isEquivalent)
2404
+ return dual(
2405
+ 2,
2406
+ (self: Iterable<A>, that: Iterable<A>): Array<A> => {
2407
+ const bs = fromIterable(that)
2408
+ return fromIterable(self).filter((a) => !has(bs, a))
2409
+ }
2410
+ )
2411
+ }
2412
+
2413
+ /**
2414
+ * Creates a `Array` of values not included in the other given `Iterable`.
2415
+ * The order and references of result values are determined by the first `Iterable`.
2416
+ *
2417
+ * **Example**
2418
+ *
2419
+ * ```ts
2420
+ * import { Array } from "effect"
2421
+ *
2422
+ * const difference = Array.difference([1, 2, 3], [2, 3, 4])
2423
+ * console.log(difference) // [1]
2424
+ * ```
2425
+ *
2426
+ * @since 2.0.0
2427
+ */
2428
+ export const difference: {
2429
+ <A>(that: Iterable<A>): (self: Iterable<A>) => Array<A>
2430
+ <A>(self: Iterable<A>, that: Iterable<A>): Array<A>
2431
+ } = differenceWith(_equivalence)
2432
+
2433
+ /**
2434
+ * @category constructors
2435
+ * @since 2.0.0
2436
+ */
2437
+ export const empty: <A = never>() => Array<A> = () => []
2438
+
2439
+ /**
2440
+ * Constructs a new `NonEmptyArray<A>` from the specified value.
2441
+ *
2442
+ * @category constructors
2443
+ * @since 2.0.0
2444
+ */
2445
+ export const of = <A>(a: A): NonEmptyArray<A> => [a]
2446
+
2447
+ /**
2448
+ * @since 2.0.0
2449
+ */
2450
+ export declare namespace ReadonlyArray {
2451
+ /**
2452
+ * @since 2.0.0
2453
+ */
2454
+ export type Infer<S extends Iterable<any>> = S extends ReadonlyArray<infer A> ? A
2455
+ : S extends Iterable<infer A> ? A
2456
+ : never
2457
+
2458
+ /**
2459
+ * @since 2.0.0
2460
+ */
2461
+ export type With<S extends Iterable<any>, A> = S extends NonEmptyReadonlyArray<any> ? NonEmptyArray<A>
2462
+ : Array<A>
2463
+
2464
+ /**
2465
+ * @since 2.0.0
2466
+ */
2467
+ export type OrNonEmpty<
2468
+ S extends Iterable<any>,
2469
+ T extends Iterable<any>,
2470
+ A
2471
+ > = S extends NonEmptyReadonlyArray<any> ? NonEmptyArray<A>
2472
+ : T extends NonEmptyReadonlyArray<any> ? NonEmptyArray<A>
2473
+ : Array<A>
2474
+
2475
+ /**
2476
+ * @since 2.0.0
2477
+ */
2478
+ export type AndNonEmpty<
2479
+ S extends Iterable<any>,
2480
+ T extends Iterable<any>,
2481
+ A
2482
+ > = S extends NonEmptyReadonlyArray<any> ? T extends NonEmptyReadonlyArray<any> ? NonEmptyArray<A>
2483
+ : Array<A>
2484
+ : Array<A>
2485
+
2486
+ /**
2487
+ * @since 2.0.0
2488
+ */
2489
+ export type Flatten<T extends ReadonlyArray<ReadonlyArray<any>>> = T extends
2490
+ NonEmptyReadonlyArray<NonEmptyReadonlyArray<infer A>> ? NonEmptyArray<A>
2491
+ : T extends ReadonlyArray<ReadonlyArray<infer A>> ? Array<A>
2492
+ : never
2493
+ }
2494
+
2495
+ /**
2496
+ * @category mapping
2497
+ * @since 2.0.0
2498
+ */
2499
+ export const map: {
2500
+ <S extends ReadonlyArray<any>, B>(
2501
+ f: (a: ReadonlyArray.Infer<S>, i: number) => B
2502
+ ): (self: S) => ReadonlyArray.With<S, B>
2503
+ <S extends ReadonlyArray<any>, B>(self: S, f: (a: ReadonlyArray.Infer<S>, i: number) => B): ReadonlyArray.With<S, B>
2504
+ } = dual(2, <A, B>(self: ReadonlyArray<A>, f: (a: A, i: number) => B): Array<B> => self.map(f))
2505
+
2506
+ /**
2507
+ * Applies a function to each element in an array and returns a new array containing the concatenated mapped elements.
2508
+ *
2509
+ * @category sequencing
2510
+ * @since 2.0.0
2511
+ */
2512
+ export const flatMap: {
2513
+ <S extends ReadonlyArray<any>, T extends ReadonlyArray<any>>(
2514
+ f: (a: ReadonlyArray.Infer<S>, i: number) => T
2515
+ ): (self: S) => ReadonlyArray.AndNonEmpty<S, T, ReadonlyArray.Infer<T>>
2516
+ <A, B>(self: NonEmptyReadonlyArray<A>, f: (a: A, i: number) => NonEmptyReadonlyArray<B>): NonEmptyArray<B>
2517
+ <A, B>(self: ReadonlyArray<A>, f: (a: A, i: number) => ReadonlyArray<B>): Array<B>
2518
+ } = dual(
2519
+ 2,
2520
+ <A, B>(self: ReadonlyArray<A>, f: (a: A, i: number) => ReadonlyArray<B>): Array<B> => {
2521
+ if (isEmptyReadonlyArray(self)) {
2522
+ return []
2523
+ }
2524
+ const out: Array<B> = []
2525
+ for (let i = 0; i < self.length; i++) {
2526
+ const inner = f(self[i], i)
2527
+ for (let j = 0; j < inner.length; j++) {
2528
+ out.push(inner[j])
2529
+ }
2530
+ }
2531
+ return out
2532
+ }
2533
+ )
2534
+
2535
+ /**
2536
+ * Combines multiple arrays into a single array by concatenating all elements
2537
+ * from each nested array. This function ensures that the structure of nested
2538
+ * arrays is collapsed into a single, flat array.
2539
+ *
2540
+ * **Example**
2541
+ *
2542
+ * ```ts
2543
+ * import { Array } from "effect"
2544
+ *
2545
+ * const result = Array.flatten([[1, 2], [], [3, 4], [], [5, 6]])
2546
+ * console.log(result) // [1, 2, 3, 4, 5, 6]
2547
+ * ```
2548
+ *
2549
+ * @category sequencing
2550
+ * @since 2.0.0
2551
+ */
2552
+ export const flatten: <S extends ReadonlyArray<ReadonlyArray<any>>>(self: S) => ReadonlyArray.Flatten<S> = flatMap(
2553
+ identity
2554
+ ) as any
2555
+
2556
+ /**
2557
+ * Applies a function to each element of the `Iterable` and filters based on the result, keeping the transformed values where the function returns `Some`.
2558
+ * This method combines filtering and mapping functionalities, allowing transformations and filtering of elements based on a single function pass.
2559
+ *
2560
+ * **Example**
2561
+ *
2562
+ * ```ts
2563
+ * import { Array, Option } from "effect"
2564
+ *
2565
+ * const evenSquares = (x: number) => x % 2 === 0 ? Option.some(x * x) : Option.none()
2566
+ *
2567
+ * const result = Array.filterMap([1, 2, 3, 4, 5], evenSquares);
2568
+ * console.log(result) // [4, 16]
2569
+ * ```
2570
+ *
2571
+ * @category filtering
2572
+ * @since 2.0.0
2573
+ */
2574
+ export const filterMap: {
2575
+ <A, B>(f: (a: A, i: number) => Option.Option<B>): (self: Iterable<A>) => Array<B>
2576
+ <A, B>(self: Iterable<A>, f: (a: A, i: number) => Option.Option<B>): Array<B>
2577
+ } = dual(
2578
+ 2,
2579
+ <A, B>(self: Iterable<A>, f: (a: A, i: number) => Option.Option<B>): Array<B> => {
2580
+ const as = fromIterable(self)
2581
+ const out: Array<B> = []
2582
+ for (let i = 0; i < as.length; i++) {
2583
+ const o = f(as[i], i)
2584
+ if (Option.isSome(o)) {
2585
+ out.push(o.value)
2586
+ }
2587
+ }
2588
+ return out
2589
+ }
2590
+ )
2591
+
2592
+ /**
2593
+ * Applies a function to each element of the array and filters based on the result, stopping when a condition is not met.
2594
+ * This method combines filtering and mapping in a single pass, and short-circuits, i.e., stops processing, as soon as the function returns `None`.
2595
+ * This is useful when you need to transform an array but only up to the point where a certain condition holds true.
2596
+ *
2597
+ * **Example**
2598
+ *
2599
+ * ```ts
2600
+ * import { Array, Option } from "effect"
2601
+ *
2602
+ * const toSquareTillOdd = (x: number) => x % 2 === 0 ? Option.some(x * x) : Option.none()
2603
+ *
2604
+ * const result = Array.filterMapWhile([2, 4, 5], toSquareTillOdd)
2605
+ * console.log(result) // [4, 16]
2606
+ * ```
2607
+ *
2608
+ * @category filtering
2609
+ * @since 2.0.0
2610
+ */
2611
+ export const filterMapWhile: {
2612
+ <A, B>(f: (a: A, i: number) => Option.Option<B>): (self: Iterable<A>) => Array<B>
2613
+ <A, B>(self: Iterable<A>, f: (a: A, i: number) => Option.Option<B>): Array<B>
2614
+ } = dual(2, <A, B>(self: Iterable<A>, f: (a: A, i: number) => Option.Option<B>) => {
2615
+ let i = 0
2616
+ const out: Array<B> = []
2617
+ for (const a of self) {
2618
+ const b = f(a, i)
2619
+ if (Option.isSome(b)) {
2620
+ out.push(b.value)
2621
+ } else {
2622
+ break
2623
+ }
2624
+ i++
2625
+ }
2626
+ return out
2627
+ })
2628
+
2629
+ /**
2630
+ * Applies a function to each element of the `Iterable`, categorizing the results into two separate arrays.
2631
+ * This function is particularly useful for operations where each element can result in two possible types,
2632
+ * and you want to separate these types into different collections. For instance, separating validation results
2633
+ * into successes and failures.
2634
+ *
2635
+ * **Example**
2636
+ *
2637
+ * ```ts
2638
+ * import { Array, Either } from "effect";
2639
+ *
2640
+ * const isEven = (x: number) => x % 2 === 0
2641
+ *
2642
+ * const result = Array.partitionMap([1, 2, 3, 4, 5], x =>
2643
+ * isEven(x) ? Either.right(x) : Either.left(x)
2644
+ * )
2645
+ * console.log(result)
2646
+ * // [
2647
+ * // [1, 3, 5],
2648
+ * // [2, 4]
2649
+ * // ]
2650
+ * ```
2651
+ *
2652
+ * @category filtering
2653
+ * @since 2.0.0
2654
+ */
2655
+ export const partitionMap: {
2656
+ <A, B, C>(f: (a: A, i: number) => Either.Either<C, B>): (self: Iterable<A>) => [left: Array<B>, right: Array<C>]
2657
+ <A, B, C>(self: Iterable<A>, f: (a: A, i: number) => Either.Either<C, B>): [left: Array<B>, right: Array<C>]
2658
+ } = dual(
2659
+ 2,
2660
+ <A, B, C>(self: Iterable<A>, f: (a: A, i: number) => Either.Either<C, B>): [left: Array<B>, right: Array<C>] => {
2661
+ const left: Array<B> = []
2662
+ const right: Array<C> = []
2663
+ const as = fromIterable(self)
2664
+ for (let i = 0; i < as.length; i++) {
2665
+ const e = f(as[i], i)
2666
+ if (Either.isLeft(e)) {
2667
+ left.push(e.left)
2668
+ } else {
2669
+ right.push(e.right)
2670
+ }
2671
+ }
2672
+ return [left, right]
2673
+ }
2674
+ )
2675
+
2676
+ /**
2677
+ * Retrieves the `Some` values from an `Iterable` of `Option`s, collecting them into an array.
2678
+ *
2679
+ * **Example**
2680
+ *
2681
+ * ```ts
2682
+ * import { Array, Option } from "effect"
2683
+ *
2684
+ * const result = Array.getSomes([Option.some(1), Option.none(), Option.some(2)])
2685
+ * console.log(result) // [1, 2]
2686
+ * ```
2687
+ *
2688
+ * @category filtering
2689
+ * @since 2.0.0
2690
+ */
2691
+
2692
+ export const getSomes: <T extends Iterable<Option.Option<X>>, X = any>(
2693
+ self: T
2694
+ ) => Array<Option.Option.Value<ReadonlyArray.Infer<T>>> = filterMap(identity as any)
2695
+
2696
+ /**
2697
+ * Retrieves the `Left` values from an `Iterable` of `Either`s, collecting them into an array.
2698
+ *
2699
+ * **Example**
2700
+ *
2701
+ * ```ts
2702
+ * import { Array, Either } from "effect"
2703
+ *
2704
+ * const result = Array.getLefts([Either.right(1), Either.left("err"), Either.right(2)])
2705
+ * console.log(result) // ["err"]
2706
+ * ```
2707
+ *
2708
+ * @category filtering
2709
+ * @since 2.0.0
2710
+ */
2711
+ export const getLefts = <T extends Iterable<Either.Either<any, any>>>(
2712
+ self: T
2713
+ ): Array<Either.Either.Left<ReadonlyArray.Infer<T>>> => {
2714
+ const out: Array<any> = []
2715
+ for (const a of self) {
2716
+ if (Either.isLeft(a)) {
2717
+ out.push(a.left)
2718
+ }
2719
+ }
2720
+
2721
+ return out
2722
+ }
2723
+
2724
+ /**
2725
+ * Retrieves the `Right` values from an `Iterable` of `Either`s, collecting them into an array.
2726
+ *
2727
+ * **Example**
2728
+ *
2729
+ * ```ts
2730
+ * import { Array, Either } from "effect"
2731
+ *
2732
+ * const result = Array.getRights([Either.right(1), Either.left("err"), Either.right(2)])
2733
+ * console.log(result) // [1, 2]
2734
+ * ```
2735
+ *
2736
+ * @category filtering
2737
+ * @since 2.0.0
2738
+ */
2739
+ export const getRights = <T extends Iterable<Either.Either<any, any>>>(
2740
+ self: T
2741
+ ): Array<Either.Either.Right<ReadonlyArray.Infer<T>>> => {
2742
+ const out: Array<any> = []
2743
+ for (const a of self) {
2744
+ if (Either.isRight(a)) {
2745
+ out.push(a.right)
2746
+ }
2747
+ }
2748
+
2749
+ return out
2750
+ }
2751
+
2752
+ /**
2753
+ * @category filtering
2754
+ * @since 2.0.0
2755
+ */
2756
+ export const filter: {
2757
+ <A, B extends A>(refinement: (a: NoInfer<A>, i: number) => a is B): (self: Iterable<A>) => Array<B>
2758
+ <A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Array<A>
2759
+ <A, B extends A>(self: Iterable<A>, refinement: (a: A, i: number) => a is B): Array<B>
2760
+ <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Array<A>
2761
+ } = dual(
2762
+ 2,
2763
+ <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Array<A> => {
2764
+ const as = fromIterable(self)
2765
+ const out: Array<A> = []
2766
+ for (let i = 0; i < as.length; i++) {
2767
+ if (predicate(as[i], i)) {
2768
+ out.push(as[i])
2769
+ }
2770
+ }
2771
+ return out
2772
+ }
2773
+ )
2774
+
2775
+ /**
2776
+ * Separate elements based on a predicate that also exposes the index of the element.
2777
+ *
2778
+ * **Example**
2779
+ *
2780
+ * ```ts
2781
+ * import { Array } from "effect"
2782
+ *
2783
+ * const result = Array.partition([1, 2, 3, 4], n => n % 2 === 0)
2784
+ * console.log(result) // [[1, 3], [2, 4]]
2785
+ * ```
2786
+ *
2787
+ * @category filtering
2788
+ * @since 2.0.0
2789
+ */
2790
+ export const partition: {
2791
+ <A, B extends A>(refinement: (a: NoInfer<A>, i: number) => a is B): (
2792
+ self: Iterable<A>
2793
+ ) => [excluded: Array<Exclude<A, B>>, satisfying: Array<B>]
2794
+ <A>(
2795
+ predicate: (a: NoInfer<A>, i: number) => boolean
2796
+ ): (self: Iterable<A>) => [excluded: Array<A>, satisfying: Array<A>]
2797
+ <A, B extends A>(
2798
+ self: Iterable<A>,
2799
+ refinement: (a: A, i: number) => a is B
2800
+ ): [excluded: Array<Exclude<A, B>>, satisfying: Array<B>]
2801
+ <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): [excluded: Array<A>, satisfying: Array<A>]
2802
+ } = dual(
2803
+ 2,
2804
+ <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): [excluded: Array<A>, satisfying: Array<A>] => {
2805
+ const left: Array<A> = []
2806
+ const right: Array<A> = []
2807
+ const as = fromIterable(self)
2808
+ for (let i = 0; i < as.length; i++) {
2809
+ if (predicate(as[i], i)) {
2810
+ right.push(as[i])
2811
+ } else {
2812
+ left.push(as[i])
2813
+ }
2814
+ }
2815
+ return [left, right]
2816
+ }
2817
+ )
2818
+
2819
+ /**
2820
+ * Separates an `Iterable` into two arrays based on a predicate.
2821
+ *
2822
+ * @category filtering
2823
+ * @since 2.0.0
2824
+ */
2825
+ export const separate: <T extends Iterable<Either.Either<any, any>>>(
2826
+ self: T
2827
+ ) => [Array<Either.Either.Left<ReadonlyArray.Infer<T>>>, Array<Either.Either.Right<ReadonlyArray.Infer<T>>>] =
2828
+ partitionMap(identity)
2829
+
2830
+ /**
2831
+ * Reduces an array from the left.
2832
+ *
2833
+ * **Example**
2834
+ *
2835
+ * ```ts
2836
+ * import { Array } from "effect"
2837
+ *
2838
+ * const result = Array.reduce([1, 2, 3], 0, (acc, n) => acc + n)
2839
+ * console.log(result) // 6
2840
+ * ```
2841
+ *
2842
+ * @category folding
2843
+ * @since 2.0.0
2844
+ */
2845
+ export const reduce: {
2846
+ <B, A>(b: B, f: (b: B, a: A, i: number) => B): (self: Iterable<A>) => B
2847
+ <A, B>(self: Iterable<A>, b: B, f: (b: B, a: A, i: number) => B): B
2848
+ } = dual(
2849
+ 3,
2850
+ <B, A>(self: Iterable<A>, b: B, f: (b: B, a: A, i: number) => B): B =>
2851
+ fromIterable(self).reduce((b, a, i) => f(b, a, i), b)
2852
+ )
2853
+
2854
+ /**
2855
+ * Reduces an array from the right.
2856
+ *
2857
+ * **Example**
2858
+ *
2859
+ * ```ts
2860
+ * import { Array } from "effect"
2861
+ *
2862
+ * const result = Array.reduceRight([1, 2, 3], 0, (acc, n) => acc + n)
2863
+ * console.log(result) // 6
2864
+ * ```
2865
+ *
2866
+ * @category folding
2867
+ * @since 2.0.0
2868
+ */
2869
+ export const reduceRight: {
2870
+ <B, A>(b: B, f: (b: B, a: A, i: number) => B): (self: Iterable<A>) => B
2871
+ <A, B>(self: Iterable<A>, b: B, f: (b: B, a: A, i: number) => B): B
2872
+ } = dual(
2873
+ 3,
2874
+ <A, B>(self: Iterable<A>, b: B, f: (b: B, a: A, i: number) => B): B =>
2875
+ fromIterable(self).reduceRight((b, a, i) => f(b, a, i), b)
2876
+ )
2877
+
2878
+ /**
2879
+ * Lifts a predicate into an array.
2880
+ *
2881
+ * **Example**
2882
+ *
2883
+ * ```ts
2884
+ * import { Array } from "effect"
2885
+ *
2886
+ * const isEven = (n: number) => n % 2 === 0
2887
+ * const to = Array.liftPredicate(isEven)
2888
+ * console.log(to(1)) // []
2889
+ * console.log(to(2)) // [2]
2890
+ * ```
2891
+ *
2892
+ * @category lifting
2893
+ * @since 2.0.0
2894
+ */
2895
+ export const liftPredicate: { // Note: I intentionally avoid using the NoInfer pattern here.
2896
+ <A, B extends A>(refinement: Predicate.Refinement<A, B>): (a: A) => Array<B>
2897
+ <A>(predicate: Predicate.Predicate<A>): <B extends A>(b: B) => Array<B>
2898
+ } = <A>(predicate: Predicate.Predicate<A>) => <B extends A>(b: B): Array<B> => predicate(b) ? [b] : []
2899
+
2900
+ /**
2901
+ * @category lifting
2902
+ * @since 2.0.0
2903
+ */
2904
+ export const liftOption = <A extends Array<unknown>, B>(
2905
+ f: (...a: A) => Option.Option<B>
2906
+ ) =>
2907
+ (...a: A): Array<B> => fromOption(f(...a))
2908
+
2909
+ /**
2910
+ * @category conversions
2911
+ * @since 2.0.0
2912
+ */
2913
+ export const fromNullable = <A>(a: A): Array<NonNullable<A>> => a == null ? empty() : [a as NonNullable<A>]
2914
+
2915
+ /**
2916
+ * @category lifting
2917
+ * @since 2.0.0
2918
+ */
2919
+ export const liftNullable = <A extends Array<unknown>, B>(
2920
+ f: (...a: A) => B | null | undefined
2921
+ ): (...a: A) => Array<NonNullable<B>> =>
2922
+ (...a) => fromNullable(f(...a))
2923
+
2924
+ /**
2925
+ * Maps over an array and flattens the result, removing null and undefined values.
2926
+ *
2927
+ * **Example**
2928
+ *
2929
+ * ```ts
2930
+ * import { Array } from "effect"
2931
+ *
2932
+ * const result = Array.flatMapNullable([1, 2, 3], n => (n % 2 === 0 ? null : n))
2933
+ * console.log(result) // [1, 3]
2934
+ *
2935
+ * // Explanation:
2936
+ * // The array of numbers [1, 2, 3] is mapped with a function that returns null for even numbers
2937
+ * // and the number itself for odd numbers. The resulting array [1, null, 3] is then flattened
2938
+ * // to remove null values, resulting in [1, 3].
2939
+ * ```
2940
+ *
2941
+ * @category sequencing
2942
+ * @since 2.0.0
2943
+ */
2944
+ export const flatMapNullable: {
2945
+ <A, B>(f: (a: A) => B | null | undefined): (self: ReadonlyArray<A>) => Array<NonNullable<B>>
2946
+ <A, B>(self: ReadonlyArray<A>, f: (a: A) => B | null | undefined): Array<NonNullable<B>>
2947
+ } = dual(
2948
+ 2,
2949
+ <A, B>(self: ReadonlyArray<A>, f: (a: A) => B | null | undefined): Array<NonNullable<B>> =>
2950
+ flatMap(self, (a) => fromNullable(f(a)))
2951
+ )
2952
+
2953
+ /**
2954
+ * Lifts a function that returns an `Either` into a function that returns an array.
2955
+ * If the `Either` is a left, it returns an empty array.
2956
+ * If the `Either` is a right, it returns an array with the right value.
2957
+ *
2958
+ * **Example**
2959
+ *
2960
+ * ```ts
2961
+ * import { Array, Either } from "effect"
2962
+ *
2963
+ * const parseNumber = (s: string): Either.Either<number, Error> =>
2964
+ * isNaN(Number(s)) ? Either.left(new Error("Not a number")) : Either.right(Number(s))
2965
+ *
2966
+ * const liftedParseNumber = Array.liftEither(parseNumber)
2967
+ *
2968
+ * const result1 = liftedParseNumber("42")
2969
+ * console.log(result1) // [42]
2970
+ *
2971
+ * const result2 = liftedParseNumber("not a number")
2972
+ * console.log(result2) // []
2973
+ *
2974
+ * // Explanation:
2975
+ * // The function parseNumber is lifted to return an array.
2976
+ * // When parsing "42", it returns an Either.left with the number 42, resulting in [42].
2977
+ * // When parsing "not a number", it returns an Either.right with an error, resulting in an empty array [].
2978
+ * ```
2979
+ *
2980
+ * @category lifting
2981
+ * @since 2.0.0
2982
+ */
2983
+ export const liftEither = <A extends Array<unknown>, E, B>(
2984
+ f: (...a: A) => Either.Either<B, E>
2985
+ ) =>
2986
+ (...a: A): Array<B> => {
2987
+ const e = f(...a)
2988
+ return Either.isLeft(e) ? [] : [e.right]
2989
+ }
2990
+
2991
+ /**
2992
+ * Check if a predicate holds true for every `ReadonlyArray` element.
2993
+ *
2994
+ * @category elements
2995
+ * @since 2.0.0
2996
+ */
2997
+ export const every: {
2998
+ <A, B extends A>(
2999
+ refinement: (a: NoInfer<A>, i: number) => a is B
3000
+ ): (self: ReadonlyArray<A>) => self is ReadonlyArray<B>
3001
+ <A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: ReadonlyArray<A>) => boolean
3002
+ <A, B extends A>(self: ReadonlyArray<A>, refinement: (a: A, i: number) => a is B): self is ReadonlyArray<B>
3003
+ <A>(self: ReadonlyArray<A>, predicate: (a: A, i: number) => boolean): boolean
3004
+ } = dual(
3005
+ 2,
3006
+ <A, B extends A>(self: ReadonlyArray<A>, refinement: (a: A, i: number) => a is B): self is ReadonlyArray<B> =>
3007
+ self.every(refinement)
3008
+ )
3009
+
3010
+ /**
3011
+ * Check if a predicate holds true for some `ReadonlyArray` element.
3012
+ *
3013
+ * @category elements
3014
+ * @since 2.0.0
3015
+ */
3016
+ export const some: {
3017
+ <A>(
3018
+ predicate: (a: NoInfer<A>, i: number) => boolean
3019
+ ): (self: ReadonlyArray<A>) => self is NonEmptyReadonlyArray<A>
3020
+ <A>(self: ReadonlyArray<A>, predicate: (a: A, i: number) => boolean): self is NonEmptyReadonlyArray<A>
3021
+ } = dual(
3022
+ 2,
3023
+ <A>(self: ReadonlyArray<A>, predicate: (a: A, i: number) => boolean): self is NonEmptyReadonlyArray<A> =>
3024
+ self.some(predicate)
3025
+ )
3026
+
3027
+ /**
3028
+ * Extends an array with a function that maps each subarray to a value.
3029
+ *
3030
+ * **Example**
3031
+ *
3032
+ * ```ts
3033
+ * import { Array } from "effect"
3034
+ *
3035
+ * const result = Array.extend([1, 2, 3], as => as.length)
3036
+ * console.log(result) // [3, 2, 1]
3037
+ *
3038
+ * // Explanation:
3039
+ * // The function maps each subarray starting from each element to its length.
3040
+ * // The subarrays are: [1, 2, 3], [2, 3], [3].
3041
+ * // The lengths are: 3, 2, 1.
3042
+ * // Therefore, the result is [3, 2, 1].
3043
+ * ```
3044
+ *
3045
+ * @since 2.0.0
3046
+ */
3047
+ export const extend: {
3048
+ <A, B>(f: (as: ReadonlyArray<A>) => B): (self: ReadonlyArray<A>) => Array<B>
3049
+ <A, B>(self: ReadonlyArray<A>, f: (as: ReadonlyArray<A>) => B): Array<B>
3050
+ } = dual(
3051
+ 2,
3052
+ <A, B>(self: ReadonlyArray<A>, f: (as: ReadonlyArray<A>) => B): Array<B> => self.map((_, i, as) => f(as.slice(i)))
3053
+ )
3054
+
3055
+ /**
3056
+ * Finds the minimum element in an array based on a comparator.
3057
+ *
3058
+ * **Example**
3059
+ *
3060
+ * ```ts
3061
+ * import { Array, Order } from "effect"
3062
+ *
3063
+ * const result = Array.min([3, 1, 2], Order.number)
3064
+ * console.log(result) // 1
3065
+ * ```
3066
+ *
3067
+ * @since 2.0.0
3068
+ */
3069
+ export const min: {
3070
+ <A>(O: Order.Order<A>): (self: NonEmptyReadonlyArray<A>) => A
3071
+ <A>(self: NonEmptyReadonlyArray<A>, O: Order.Order<A>): A
3072
+ } = dual(2, <A>(self: NonEmptyReadonlyArray<A>, O: Order.Order<A>): A => self.reduce(Order.min(O)))
3073
+
3074
+ /**
3075
+ * Finds the maximum element in an array based on a comparator.
3076
+ *
3077
+ * **Example**
3078
+ *
3079
+ * ```ts
3080
+ * import { Array, Order } from "effect"
3081
+ *
3082
+ * const result = Array.max([3, 1, 2], Order.number)
3083
+ * console.log(result) // 3
3084
+ * ```
3085
+ *
3086
+ * @since 2.0.0
3087
+ */
3088
+ export const max: {
3089
+ <A>(O: Order.Order<A>): (self: NonEmptyReadonlyArray<A>) => A
3090
+ <A>(self: NonEmptyReadonlyArray<A>, O: Order.Order<A>): A
3091
+ } = dual(2, <A>(self: NonEmptyReadonlyArray<A>, O: Order.Order<A>): A => self.reduce(Order.max(O)))
3092
+
3093
+ /**
3094
+ * @category constructors
3095
+ * @since 2.0.0
3096
+ */
3097
+ export const unfold = <B, A>(b: B, f: (b: B) => Option.Option<readonly [A, B]>): Array<A> => {
3098
+ const out: Array<A> = []
3099
+ let next: B = b
3100
+ let o: Option.Option<readonly [A, B]>
3101
+ while (Option.isSome(o = f(next))) {
3102
+ const [a, b] = o.value
3103
+ out.push(a)
3104
+ next = b
3105
+ }
3106
+ return out
3107
+ }
3108
+
3109
+ /**
3110
+ * This function creates and returns a new `Order` for an array of values based on a given `Order` for the elements of the array.
3111
+ * The returned `Order` compares two arrays by applying the given `Order` to each element in the arrays.
3112
+ * If all elements are equal, the arrays are then compared based on their length.
3113
+ * It is useful when you need to compare two arrays of the same type and you have a specific way of comparing each element of the array.
3114
+ *
3115
+ * @category instances
3116
+ * @since 2.0.0
3117
+ */
3118
+ export const getOrder: <A>(O: Order.Order<A>) => Order.Order<ReadonlyArray<A>> = Order.array
3119
+
3120
+ /**
3121
+ * Creates an equivalence relation for arrays.
3122
+ *
3123
+ * **Example**
3124
+ *
3125
+ * ```ts
3126
+ * import { Array } from "effect"
3127
+ *
3128
+ * const eq = Array.getEquivalence<number>((a, b) => a === b)
3129
+ * console.log(eq([1, 2, 3], [1, 2, 3])) // true
3130
+ * ```
3131
+ *
3132
+ * @category instances
3133
+ * @since 2.0.0
3134
+ */
3135
+ export const getEquivalence: <A>(
3136
+ isEquivalent: Equivalence.Equivalence<A>
3137
+ ) => Equivalence.Equivalence<ReadonlyArray<A>> = Equivalence.array
3138
+
3139
+ /**
3140
+ * Performs a side-effect for each element of the `Iterable`.
3141
+ *
3142
+ * **Example**
3143
+ *
3144
+ * ```ts
3145
+ * import { Array } from "effect"
3146
+ *
3147
+ * Array.forEach([1, 2, 3], n => console.log(n)) // 1, 2, 3
3148
+ * ```
3149
+ *
3150
+ * @since 2.0.0
3151
+ */
3152
+ export const forEach: {
3153
+ <A>(f: (a: A, i: number) => void): (self: Iterable<A>) => void
3154
+ <A>(self: Iterable<A>, f: (a: A, i: number) => void): void
3155
+ } = dual(2, <A>(self: Iterable<A>, f: (a: A, i: number) => void): void => fromIterable(self).forEach((a, i) => f(a, i)))
3156
+
3157
+ /**
3158
+ * Remove duplicates from an `Iterable` using the provided `isEquivalent` function,
3159
+ * preserving the order of the first occurrence of each element.
3160
+ *
3161
+ * **Example**
3162
+ *
3163
+ * ```ts
3164
+ * import { Array } from "effect"
3165
+ *
3166
+ * const result = Array.dedupeWith([1, 2, 2, 3, 3, 3], (a, b) => a === b)
3167
+ * console.log(result) // [1, 2, 3]
3168
+ * ```
3169
+ *
3170
+ * @since 2.0.0
3171
+ */
3172
+ export const dedupeWith: {
3173
+ <S extends Iterable<any>>(
3174
+ isEquivalent: (self: ReadonlyArray.Infer<S>, that: ReadonlyArray.Infer<S>) => boolean
3175
+ ): (self: S) => ReadonlyArray.With<S, ReadonlyArray.Infer<S>>
3176
+ <A>(self: NonEmptyReadonlyArray<A>, isEquivalent: (self: A, that: A) => boolean): NonEmptyArray<A>
3177
+ <A>(self: Iterable<A>, isEquivalent: (self: A, that: A) => boolean): Array<A>
3178
+ } = dual(
3179
+ 2,
3180
+ <A>(self: Iterable<A>, isEquivalent: (self: A, that: A) => boolean): Array<A> => {
3181
+ const input = fromIterable(self)
3182
+ if (isNonEmptyReadonlyArray(input)) {
3183
+ const out: NonEmptyArray<A> = [headNonEmpty(input)]
3184
+ const rest = tailNonEmpty(input)
3185
+ for (const r of rest) {
3186
+ if (out.every((a) => !isEquivalent(r, a))) {
3187
+ out.push(r)
3188
+ }
3189
+ }
3190
+ return out
3191
+ }
3192
+ return []
3193
+ }
3194
+ )
3195
+
3196
+ /**
3197
+ * Remove duplicates from an `Iterable`, preserving the order of the first occurrence of each element.
3198
+ * The equivalence used to compare elements is provided by `Equal.equivalence()` from the `Equal` module.
3199
+ *
3200
+ * @since 2.0.0
3201
+ */
3202
+ export const dedupe = <S extends Iterable<any>>(
3203
+ self: S
3204
+ ): S extends NonEmptyReadonlyArray<infer A> ? NonEmptyArray<A> : S extends Iterable<infer A> ? Array<A> : never =>
3205
+ dedupeWith(self, Equal.equivalence()) as any
3206
+
3207
+ /**
3208
+ * Deduplicates adjacent elements that are identical using the provided `isEquivalent` function.
3209
+ *
3210
+ * **Example**
3211
+ *
3212
+ * ```ts
3213
+ * import { Array } from "effect"
3214
+ *
3215
+ * const result = Array.dedupeAdjacentWith([1, 1, 2, 2, 3, 3], (a, b) => a === b)
3216
+ * console.log(result) // [1, 2, 3]
3217
+ * ```
3218
+ *
3219
+ * @since 2.0.0
3220
+ */
3221
+ export const dedupeAdjacentWith: {
3222
+ <A>(isEquivalent: (self: A, that: A) => boolean): (self: Iterable<A>) => Array<A>
3223
+ <A>(self: Iterable<A>, isEquivalent: (self: A, that: A) => boolean): Array<A>
3224
+ } = dual(2, <A>(self: Iterable<A>, isEquivalent: (self: A, that: A) => boolean): Array<A> => {
3225
+ const out: Array<A> = []
3226
+ let lastA: Option.Option<A> = Option.none()
3227
+ for (const a of self) {
3228
+ if (Option.isNone(lastA) || !isEquivalent(a, lastA.value)) {
3229
+ out.push(a)
3230
+ lastA = Option.some(a)
3231
+ }
3232
+ }
3233
+ return out
3234
+ })
3235
+
3236
+ /**
3237
+ * Deduplicates adjacent elements that are identical.
3238
+ *
3239
+ * **Example**
3240
+ *
3241
+ * ```ts
3242
+ * import { Array } from "effect"
3243
+ *
3244
+ * const result = Array.dedupeAdjacent([1, 1, 2, 2, 3, 3])
3245
+ * console.log(result) // [1, 2, 3]
3246
+ * ```
3247
+ *
3248
+ * @since 2.0.0
3249
+ */
3250
+ export const dedupeAdjacent: <A>(self: Iterable<A>) => Array<A> = dedupeAdjacentWith(Equal.equivalence())
3251
+
3252
+ /**
3253
+ * Joins the elements together with "sep" in the middle.
3254
+ *
3255
+ * **Example**
3256
+ *
3257
+ * ```ts
3258
+ * import { Array } from "effect"
3259
+ *
3260
+ * const strings = ["a", "b", "c"]
3261
+ * const joined = Array.join(strings, "-")
3262
+ * console.log(joined) // "a-b-c"
3263
+ * ```
3264
+ *
3265
+ * @since 2.0.0
3266
+ * @category folding
3267
+ */
3268
+ export const join: {
3269
+ (sep: string): (self: Iterable<string>) => string
3270
+ (self: Iterable<string>, sep: string): string
3271
+ } = dual(2, (self: Iterable<string>, sep: string): string => fromIterable(self).join(sep))
3272
+
3273
+ /**
3274
+ * Statefully maps over the chunk, producing new elements of type `B`.
3275
+ *
3276
+ * **Example**
3277
+ *
3278
+ * ```ts
3279
+ * import { Array } from "effect"
3280
+ *
3281
+ * const result = Array.mapAccum([1, 2, 3], 0, (acc, n) => [acc + n, acc + n])
3282
+ * console.log(result) // [6, [1, 3, 6]]
3283
+ * ```
3284
+ *
3285
+ * @since 2.0.0
3286
+ * @category folding
3287
+ */
3288
+ export const mapAccum: {
3289
+ <S, A, B, I extends Iterable<A> = Iterable<A>>(
3290
+ s: S,
3291
+ f: (s: S, a: ReadonlyArray.Infer<I>, i: number) => readonly [S, B]
3292
+ ): (self: I) => [state: S, mappedArray: ReadonlyArray.With<I, B>]
3293
+ <S, A, B, I extends Iterable<A> = Iterable<A>>(
3294
+ self: I,
3295
+ s: S,
3296
+ f: (s: S, a: ReadonlyArray.Infer<I>, i: number) => readonly [S, B]
3297
+ ): [state: S, mappedArray: ReadonlyArray.With<I, B>]
3298
+ } = dual(
3299
+ 3,
3300
+ <S, A, B>(self: Iterable<A>, s: S, f: (s: S, a: A, i: number) => [S, B]): [state: S, mappedArray: Array<B>] => {
3301
+ let i = 0
3302
+ let s1 = s
3303
+ const out: Array<B> = []
3304
+ for (const a of self) {
3305
+ const r = f(s1, a, i)
3306
+ s1 = r[0]
3307
+ out.push(r[1])
3308
+ i++
3309
+ }
3310
+ return [s1, out]
3311
+ }
3312
+ )
3313
+
3314
+ /**
3315
+ * Zips this chunk crosswise with the specified chunk using the specified combiner.
3316
+ *
3317
+ * **Example**
3318
+ *
3319
+ * ```ts
3320
+ * import { Array } from "effect"
3321
+ *
3322
+ * const result = Array.cartesianWith([1, 2], ["a", "b"], (a, b) => `${a}-${b}`)
3323
+ * console.log(result) // ["1-a", "1-b", "2-a", "2-b"]
3324
+ * ```
3325
+ *
3326
+ * @since 2.0.0
3327
+ * @category elements
3328
+ */
3329
+ export const cartesianWith: {
3330
+ <A, B, C>(that: ReadonlyArray<B>, f: (a: A, b: B) => C): (self: ReadonlyArray<A>) => Array<C>
3331
+ <A, B, C>(self: ReadonlyArray<A>, that: ReadonlyArray<B>, f: (a: A, b: B) => C): Array<C>
3332
+ } = dual(
3333
+ 3,
3334
+ <A, B, C>(self: ReadonlyArray<A>, that: ReadonlyArray<B>, f: (a: A, b: B) => C): Array<C> =>
3335
+ flatMap(self, (a) => map(that, (b) => f(a, b)))
3336
+ )
3337
+
3338
+ /**
3339
+ * Zips this chunk crosswise with the specified chunk.
3340
+ *
3341
+ * **Example**
3342
+ *
3343
+ * ```ts
3344
+ * import { Array } from "effect"
3345
+ *
3346
+ * const result = Array.cartesian([1, 2], ["a", "b"])
3347
+ * console.log(result) // [[1, "a"], [1, "b"], [2, "a"], [2, "b"]]
3348
+ * ```
3349
+ *
3350
+ * @since 2.0.0
3351
+ * @category elements
3352
+ */
3353
+ export const cartesian: {
3354
+ <B>(that: ReadonlyArray<B>): <A>(self: ReadonlyArray<A>) => Array<[A, B]>
3355
+ <A, B>(self: ReadonlyArray<A>, that: ReadonlyArray<B>): Array<[A, B]>
3356
+ } = dual(
3357
+ 2,
3358
+ <A, B>(self: ReadonlyArray<A>, that: ReadonlyArray<B>): Array<[A, B]> => cartesianWith(self, that, (a, b) => [a, b])
3359
+ )
3360
+
3361
+ // -------------------------------------------------------------------------------------
3362
+ // do notation
3363
+ // -------------------------------------------------------------------------------------
3364
+
3365
+ /**
3366
+ * The "do simulation" for array allows you to sequentially apply operations to the elements of arrays, just as nested loops allow you to go through all combinations of elements in an arrays.
3367
+ *
3368
+ * It can be used to simulate "array comprehension".
3369
+ * It's a technique that allows you to create new arrays by iterating over existing ones and applying specific **conditions** or **transformations** to the elements. It's like assembling a new collection from pieces of other collections based on certain rules.
3370
+ *
3371
+ * Here's how the do simulation works:
3372
+ *
3373
+ * 1. Start the do simulation using the `Do` value
3374
+ * 2. Within the do simulation scope, you can use the `bind` function to define variables and bind them to `Array` values
3375
+ * 3. You can accumulate multiple `bind` statements to define multiple variables within the scope
3376
+ * 4. Inside the do simulation scope, you can also use the `let` function to define variables and bind them to simple values
3377
+ * 5. Regular `Array` functions like `map` and `filter` can still be used within the do simulation. These functions will receive the accumulated variables as arguments within the scope
3378
+ *
3379
+ * **Example**
3380
+ *
3381
+ * ```ts
3382
+ * import { Array, pipe } from "effect"
3383
+ *
3384
+ * const doResult = pipe(
3385
+ * Array.Do,
3386
+ * Array.bind("x", () => [1, 3, 5]),
3387
+ * Array.bind("y", () => [2, 4, 6]),
3388
+ * Array.filter(({ x, y }) => x < y), // condition
3389
+ * Array.map(({ x, y }) => [x, y] as const) // transformation
3390
+ * )
3391
+ * console.log(doResult) // [[1, 2], [1, 4], [1, 6], [3, 4], [3, 6], [5, 6]]
3392
+ *
3393
+ * // equivalent
3394
+ * const x = [1, 3, 5],
3395
+ * y = [2, 4, 6],
3396
+ * result = [];
3397
+ * for(let i = 0; i < x.length; i++) {
3398
+ * for(let j = 0; j < y.length; j++) {
3399
+ * const _x = x[i], _y = y[j];
3400
+ * if(_x < _y) result.push([_x, _y] as const)
3401
+ * }
3402
+ * }
3403
+ * ```
3404
+ *
3405
+ * @see {@link bindTo}
3406
+ * @see {@link bind}
3407
+ * @see {@link let_ let}
3408
+ *
3409
+ * @category do notation
3410
+ * @since 3.2.0
3411
+ */
3412
+ export const Do: ReadonlyArray<{}> = of({})
3413
+
3414
+ /**
3415
+ * The "do simulation" for array allows you to sequentially apply operations to the elements of arrays, just as nested loops allow you to go through all combinations of elements in an arrays.
3416
+ *
3417
+ * It can be used to simulate "array comprehension".
3418
+ * It's a technique that allows you to create new arrays by iterating over existing ones and applying specific **conditions** or **transformations** to the elements. It's like assembling a new collection from pieces of other collections based on certain rules.
3419
+ *
3420
+ * Here's how the do simulation works:
3421
+ *
3422
+ * 1. Start the do simulation using the `Do` value
3423
+ * 2. Within the do simulation scope, you can use the `bind` function to define variables and bind them to `Array` values
3424
+ * 3. You can accumulate multiple `bind` statements to define multiple variables within the scope
3425
+ * 4. Inside the do simulation scope, you can also use the `let` function to define variables and bind them to simple values
3426
+ * 5. Regular `Array` functions like `map` and `filter` can still be used within the do simulation. These functions will receive the accumulated variables as arguments within the scope
3427
+ *
3428
+ * **Example**
3429
+ *
3430
+ * ```ts
3431
+ * import { Array, pipe } from "effect"
3432
+ *
3433
+ * const doResult = pipe(
3434
+ * Array.Do,
3435
+ * Array.bind("x", () => [1, 3, 5]),
3436
+ * Array.bind("y", () => [2, 4, 6]),
3437
+ * Array.filter(({ x, y }) => x < y), // condition
3438
+ * Array.map(({ x, y }) => [x, y] as const) // transformation
3439
+ * )
3440
+ * console.log(doResult) // [[1, 2], [1, 4], [1, 6], [3, 4], [3, 6], [5, 6]]
3441
+ *
3442
+ * // equivalent
3443
+ * const x = [1, 3, 5],
3444
+ * y = [2, 4, 6],
3445
+ * result = [];
3446
+ * for(let i = 0; i < x.length; i++) {
3447
+ * for(let j = 0; j < y.length; j++) {
3448
+ * const _x = x[i], _y = y[j];
3449
+ * if(_x < _y) result.push([_x, _y] as const)
3450
+ * }
3451
+ * }
3452
+ * ```
3453
+ *
3454
+ * @see {@link bindTo}
3455
+ * @see {@link Do}
3456
+ * @see {@link let_ let}
3457
+ *
3458
+ * @category do notation
3459
+ * @since 3.2.0
3460
+ */
3461
+ export const bind: {
3462
+ <A extends object, N extends string, B>(
3463
+ tag: Exclude<N, keyof A>,
3464
+ f: (a: NoInfer<A>) => ReadonlyArray<B>
3465
+ ): (
3466
+ self: ReadonlyArray<A>
3467
+ ) => Array<{ [K in N | keyof A]: K extends keyof A ? A[K] : B }>
3468
+ <A extends object, N extends string, B>(
3469
+ self: ReadonlyArray<A>,
3470
+ tag: Exclude<N, keyof A>,
3471
+ f: (a: NoInfer<A>) => ReadonlyArray<B>
3472
+ ): Array<{ [K in N | keyof A]: K extends keyof A ? A[K] : B }>
3473
+ } = internalDoNotation.bind<ReadonlyArrayTypeLambda>(map, flatMap) as any
3474
+
3475
+ /**
3476
+ * The "do simulation" for array allows you to sequentially apply operations to the elements of arrays, just as nested loops allow you to go through all combinations of elements in an arrays.
3477
+ *
3478
+ * It can be used to simulate "array comprehension".
3479
+ * It's a technique that allows you to create new arrays by iterating over existing ones and applying specific **conditions** or **transformations** to the elements. It's like assembling a new collection from pieces of other collections based on certain rules.
3480
+ *
3481
+ * Here's how the do simulation works:
3482
+ *
3483
+ * 1. Start the do simulation using the `Do` value
3484
+ * 2. Within the do simulation scope, you can use the `bind` function to define variables and bind them to `Array` values
3485
+ * 3. You can accumulate multiple `bind` statements to define multiple variables within the scope
3486
+ * 4. Inside the do simulation scope, you can also use the `let` function to define variables and bind them to simple values
3487
+ * 5. Regular `Array` functions like `map` and `filter` can still be used within the do simulation. These functions will receive the accumulated variables as arguments within the scope
3488
+ *
3489
+ * **Example**
3490
+ *
3491
+ * ```ts
3492
+ * import { Array, pipe } from "effect"
3493
+ *
3494
+ * const doResult = pipe(
3495
+ * Array.Do,
3496
+ * Array.bind("x", () => [1, 3, 5]),
3497
+ * Array.bind("y", () => [2, 4, 6]),
3498
+ * Array.filter(({ x, y }) => x < y), // condition
3499
+ * Array.map(({ x, y }) => [x, y] as const) // transformation
3500
+ * )
3501
+ * console.log(doResult) // [[1, 2], [1, 4], [1, 6], [3, 4], [3, 6], [5, 6]]
3502
+ *
3503
+ * // equivalent
3504
+ * const x = [1, 3, 5],
3505
+ * y = [2, 4, 6],
3506
+ * result = [];
3507
+ * for(let i = 0; i < x.length; i++) {
3508
+ * for(let j = 0; j < y.length; j++) {
3509
+ * const _x = x[i], _y = y[j];
3510
+ * if(_x < _y) result.push([_x, _y] as const)
3511
+ * }
3512
+ * }
3513
+ * ```
3514
+ *
3515
+ * @see {@link bindTo}
3516
+ * @see {@link Do}
3517
+ * @see {@link let_ let}
3518
+ *
3519
+ * @category do notation
3520
+ * @since 3.2.0
3521
+ */
3522
+ export const bindTo: {
3523
+ <N extends string>(tag: N): <A>(self: ReadonlyArray<A>) => Array<{ [K in N]: A }>
3524
+ <A, N extends string>(self: ReadonlyArray<A>, tag: N): Array<{ [K in N]: A }>
3525
+ } = internalDoNotation.bindTo<ReadonlyArrayTypeLambda>(map) as any
3526
+
3527
+ const let_: {
3528
+ <N extends string, B, A extends object>(
3529
+ tag: Exclude<N, keyof A>,
3530
+ f: (a: NoInfer<A>) => B
3531
+ ): (self: ReadonlyArray<A>) => Array<{ [K in N | keyof A]: K extends keyof A ? A[K] : B }>
3532
+ <N extends string, A extends object, B>(
3533
+ self: ReadonlyArray<A>,
3534
+ tag: Exclude<N, keyof A>,
3535
+ f: (a: NoInfer<A>) => B
3536
+ ): Array<{ [K in N | keyof A]: K extends keyof A ? A[K] : B }>
3537
+ } = internalDoNotation.let_<ReadonlyArrayTypeLambda>(map) as any
3538
+
3539
+ export {
3540
+ /**
3541
+ * The "do simulation" for array allows you to sequentially apply operations to the elements of arrays, just as nested loops allow you to go through all combinations of elements in an arrays.
3542
+ *
3543
+ * It can be used to simulate "array comprehension".
3544
+ * It's a technique that allows you to create new arrays by iterating over existing ones and applying specific **conditions** or **transformations** to the elements. It's like assembling a new collection from pieces of other collections based on certain rules.
3545
+ *
3546
+ * Here's how the do simulation works:
3547
+ *
3548
+ * 1. Start the do simulation using the `Do` value
3549
+ * 2. Within the do simulation scope, you can use the `bind` function to define variables and bind them to `Array` values
3550
+ * 3. You can accumulate multiple `bind` statements to define multiple variables within the scope
3551
+ * 4. Inside the do simulation scope, you can also use the `let` function to define variables and bind them to simple values
3552
+ * 5. Regular `Array` functions like `map` and `filter` can still be used within the do simulation. These functions will receive the accumulated variables as arguments within the scope
3553
+ *
3554
+ * **Example**
3555
+ *
3556
+ * ```ts
3557
+ * import { Array, pipe } from "effect"
3558
+ *
3559
+ * const doResult = pipe(
3560
+ * Array.Do,
3561
+ * Array.bind("x", () => [1, 3, 5]),
3562
+ * Array.bind("y", () => [2, 4, 6]),
3563
+ * Array.filter(({ x, y }) => x < y), // condition
3564
+ * Array.map(({ x, y }) => [x, y] as const) // transformation
3565
+ * )
3566
+ * console.log(doResult) // [[1, 2], [1, 4], [1, 6], [3, 4], [3, 6], [5, 6]]
3567
+ *
3568
+ * // equivalent
3569
+ * const x = [1, 3, 5],
3570
+ * y = [2, 4, 6],
3571
+ * result = [];
3572
+ * for(let i = 0; i < x.length; i++) {
3573
+ * for(let j = 0; j < y.length; j++) {
3574
+ * const _x = x[i], _y = y[j];
3575
+ * if(_x < _y) result.push([_x, _y] as const)
3576
+ * }
3577
+ * }
3578
+ *
3579
+ * ```
3580
+ *
3581
+ * @see {@link bindTo}
3582
+ * @see {@link bind}
3583
+ * @see {@link Do}
3584
+ *
3585
+ * @category do notation
3586
+ * @since 3.2.0
3587
+ */
3588
+ let_ as let
3589
+ }