@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.
- package/SourceLocation/package.json +6 -0
- package/dist/cjs/Effect.js +2 -28
- package/dist/cjs/Effect.js.map +1 -1
- package/dist/cjs/FiberRef.js +12 -1
- package/dist/cjs/FiberRef.js.map +1 -1
- package/dist/cjs/Layer.js +2 -24
- package/dist/cjs/Layer.js.map +1 -1
- package/dist/cjs/RuntimeFlags.js +1 -29
- package/dist/cjs/RuntimeFlags.js.map +1 -1
- package/dist/cjs/SourceLocation.js +60 -0
- package/dist/cjs/SourceLocation.js.map +1 -0
- package/dist/cjs/Tracer.js +1 -15
- package/dist/cjs/Tracer.js.map +1 -1
- package/dist/cjs/Utils.js +1 -1
- package/dist/cjs/Utils.js.map +1 -1
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/internal/clock.js +1 -1
- package/dist/cjs/internal/clock.js.map +1 -1
- package/dist/cjs/internal/core.js +17 -50
- package/dist/cjs/internal/core.js.map +1 -1
- package/dist/cjs/internal/effect/circular.js +18 -30
- package/dist/cjs/internal/effect/circular.js.map +1 -1
- package/dist/cjs/internal/fiberRuntime.js +16 -65
- package/dist/cjs/internal/fiberRuntime.js.map +1 -1
- package/dist/cjs/internal/layer/circular.js +1 -5
- package/dist/cjs/internal/layer/circular.js.map +1 -1
- package/dist/cjs/internal/layer.js +1 -3
- package/dist/cjs/internal/layer.js.map +1 -1
- package/dist/cjs/internal/logger.js +25 -2
- package/dist/cjs/internal/logger.js.map +1 -1
- package/dist/cjs/internal/runtimeFlags.js +2 -11
- package/dist/cjs/internal/runtimeFlags.js.map +1 -1
- package/dist/cjs/internal/tracer.js +1 -114
- package/dist/cjs/internal/tracer.js.map +1 -1
- package/dist/dts/Config.d.ts +2 -2
- package/dist/dts/Config.d.ts.map +1 -1
- package/dist/dts/Effect.d.ts +8 -29
- package/dist/dts/Effect.d.ts.map +1 -1
- package/dist/dts/FiberRef.d.ts +12 -0
- package/dist/dts/FiberRef.d.ts.map +1 -1
- package/dist/dts/Layer.d.ts +0 -22
- package/dist/dts/Layer.d.ts.map +1 -1
- package/dist/dts/RuntimeFlags.d.ts +0 -28
- package/dist/dts/RuntimeFlags.d.ts.map +1 -1
- package/dist/dts/SourceLocation.d.ts +88 -0
- package/dist/dts/SourceLocation.d.ts.map +1 -0
- package/dist/dts/Tracer.d.ts +0 -15
- package/dist/dts/Tracer.d.ts.map +1 -1
- package/dist/dts/index.d.ts +6 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/internal/core.d.ts.map +1 -1
- package/dist/dts/internal/layer.d.ts.map +1 -1
- package/dist/dts/internal/runtimeFlags.d.ts.map +1 -1
- package/dist/esm/Effect.js +0 -26
- package/dist/esm/Effect.js.map +1 -1
- package/dist/esm/FiberRef.js +11 -0
- package/dist/esm/FiberRef.js.map +1 -1
- package/dist/esm/Layer.js +0 -22
- package/dist/esm/Layer.js.map +1 -1
- package/dist/esm/RuntimeFlags.js +0 -28
- package/dist/esm/RuntimeFlags.js.map +1 -1
- package/dist/esm/SourceLocation.js +51 -0
- package/dist/esm/SourceLocation.js.map +1 -0
- package/dist/esm/Tracer.js +0 -14
- package/dist/esm/Tracer.js.map +1 -1
- package/dist/esm/Utils.js +1 -1
- package/dist/esm/Utils.js.map +1 -1
- package/dist/esm/index.js +6 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal/clock.js +1 -1
- package/dist/esm/internal/clock.js.map +1 -1
- package/dist/esm/internal/core.js +12 -45
- package/dist/esm/internal/core.js.map +1 -1
- package/dist/esm/internal/effect/circular.js +18 -30
- package/dist/esm/internal/effect/circular.js.map +1 -1
- package/dist/esm/internal/fiberRuntime.js +13 -60
- package/dist/esm/internal/fiberRuntime.js.map +1 -1
- package/dist/esm/internal/layer/circular.js +0 -4
- package/dist/esm/internal/layer/circular.js.map +1 -1
- package/dist/esm/internal/layer.js +0 -2
- package/dist/esm/internal/layer.js.map +1 -1
- package/dist/esm/internal/logger.js +25 -2
- package/dist/esm/internal/logger.js.map +1 -1
- package/dist/esm/internal/runtimeFlags.js +1 -9
- package/dist/esm/internal/runtimeFlags.js.map +1 -1
- package/dist/esm/internal/tracer.js +0 -111
- package/dist/esm/internal/tracer.js.map +1 -1
- package/package.json +12 -1
- package/src/Arbitrary.ts +1101 -0
- package/src/Array.ts +3589 -0
- package/src/BigDecimal.ts +1349 -0
- package/src/BigInt.ts +643 -0
- package/src/Boolean.ts +287 -0
- package/src/Brand.ts +360 -0
- package/src/Cache.ts +281 -0
- package/src/Cause.ts +1555 -0
- package/src/Channel.ts +2355 -0
- package/src/ChildExecutorDecision.ts +146 -0
- package/src/Chunk.ts +1495 -0
- package/src/Clock.ts +111 -0
- package/src/Config.ts +542 -0
- package/src/ConfigError.ts +270 -0
- package/src/ConfigProvider.ts +333 -0
- package/src/ConfigProviderPathPatch.ts +100 -0
- package/src/Console.ts +226 -0
- package/src/Context.ts +585 -0
- package/src/Cron.ts +706 -0
- package/src/Data.ts +596 -0
- package/src/DateTime.ts +1686 -0
- package/src/DefaultServices.ts +34 -0
- package/src/Deferred.ts +301 -0
- package/src/Differ.ts +450 -0
- package/src/Duration.ts +1000 -0
- package/src/Effect.ts +14817 -0
- package/src/Effectable.ts +107 -0
- package/src/Either.ts +1040 -0
- package/src/Encoding.ts +195 -0
- package/src/Equal.ts +98 -0
- package/src/Equivalence.ts +235 -0
- package/src/ExecutionPlan.ts +308 -0
- package/src/ExecutionStrategy.ts +119 -0
- package/src/Exit.ts +467 -0
- package/src/FastCheck.ts +9 -0
- package/src/Fiber.ts +744 -0
- package/src/FiberHandle.ts +540 -0
- package/src/FiberId.ts +195 -0
- package/src/FiberMap.ts +656 -0
- package/src/FiberRef.ts +444 -0
- package/src/FiberRefs.ts +204 -0
- package/src/FiberRefsPatch.ts +105 -0
- package/src/FiberSet.ts +491 -0
- package/src/FiberStatus.ts +108 -0
- package/src/Function.ts +1222 -0
- package/src/GlobalValue.ts +53 -0
- package/src/Graph.ts +3732 -0
- package/src/GroupBy.ts +103 -0
- package/src/HKT.ts +45 -0
- package/src/Hash.ts +195 -0
- package/src/HashMap.ts +519 -0
- package/src/HashRing.ts +317 -0
- package/src/HashSet.ts +2346 -0
- package/src/Inspectable.ts +287 -0
- package/src/Iterable.ts +1119 -0
- package/src/JSONSchema.ts +1044 -0
- package/src/KeyedPool.ts +167 -0
- package/src/Layer.ts +1228 -0
- package/src/LayerMap.ts +436 -0
- package/src/List.ts +977 -0
- package/src/LogLevel.ts +285 -0
- package/src/LogSpan.ts +25 -0
- package/src/Logger.ts +702 -0
- package/src/Mailbox.ts +268 -0
- package/src/ManagedRuntime.ts +180 -0
- package/src/Match.ts +1477 -0
- package/src/MergeDecision.ts +95 -0
- package/src/MergeState.ts +172 -0
- package/src/MergeStrategy.ts +107 -0
- package/src/Metric.ts +780 -0
- package/src/MetricBoundaries.ts +69 -0
- package/src/MetricHook.ts +151 -0
- package/src/MetricKey.ts +224 -0
- package/src/MetricKeyType.ts +262 -0
- package/src/MetricLabel.ts +47 -0
- package/src/MetricPair.ts +71 -0
- package/src/MetricPolling.ts +148 -0
- package/src/MetricRegistry.ts +48 -0
- package/src/MetricState.ts +257 -0
- package/src/Micro.ts +4405 -0
- package/src/ModuleVersion.ts +18 -0
- package/src/MutableHashMap.ts +411 -0
- package/src/MutableHashSet.ts +706 -0
- package/src/MutableList.ts +297 -0
- package/src/MutableQueue.ts +227 -0
- package/src/MutableRef.ts +202 -0
- package/src/NonEmptyIterable.ts +32 -0
- package/src/Number.ts +1071 -0
- package/src/Option.ts +2170 -0
- package/src/Order.ts +373 -0
- package/src/Ordering.ts +111 -0
- package/src/ParseResult.ts +2031 -0
- package/src/PartitionedSemaphore.ts +200 -0
- package/src/Pipeable.ts +566 -0
- package/src/Pool.ts +204 -0
- package/src/Predicate.ts +1405 -0
- package/src/Pretty.ts +205 -0
- package/src/PrimaryKey.ts +23 -0
- package/src/PubSub.ts +182 -0
- package/src/Queue.ts +644 -0
- package/src/Random.ts +204 -0
- package/src/RateLimiter.ts +138 -0
- package/src/RcMap.ts +141 -0
- package/src/RcRef.ts +122 -0
- package/src/Readable.ts +93 -0
- package/src/Record.ts +1274 -0
- package/src/RedBlackTree.ts +421 -0
- package/src/Redacted.ts +144 -0
- package/src/Ref.ts +180 -0
- package/src/RegExp.ts +38 -0
- package/src/Reloadable.ts +127 -0
- package/src/Request.ts +347 -0
- package/src/RequestBlock.ts +118 -0
- package/src/RequestResolver.ts +366 -0
- package/src/Resource.ts +119 -0
- package/src/Runtime.ts +383 -0
- package/src/RuntimeFlags.ts +336 -0
- package/src/RuntimeFlagsPatch.ts +183 -0
- package/src/STM.ts +2045 -0
- package/src/Schedule.ts +2219 -0
- package/src/ScheduleDecision.ts +62 -0
- package/src/ScheduleInterval.ts +151 -0
- package/src/ScheduleIntervals.ts +122 -0
- package/src/Scheduler.ts +353 -0
- package/src/Schema.ts +10914 -0
- package/src/SchemaAST.ts +3043 -0
- package/src/Scope.ts +204 -0
- package/src/ScopedCache.ts +151 -0
- package/src/ScopedRef.ts +117 -0
- package/src/Secret.ts +88 -0
- package/src/SingleProducerAsyncInput.ts +67 -0
- package/src/Sink.ts +1461 -0
- package/src/SortedMap.ts +287 -0
- package/src/SortedSet.ts +390 -0
- package/src/SourceLocation.ts +108 -0
- package/src/Stream.ts +6468 -0
- package/src/StreamEmit.ts +136 -0
- package/src/StreamHaltStrategy.ts +123 -0
- package/src/Streamable.ts +45 -0
- package/src/String.ts +778 -0
- package/src/Struct.ts +243 -0
- package/src/Subscribable.ts +100 -0
- package/src/SubscriptionRef.ts +298 -0
- package/src/Supervisor.ts +240 -0
- package/src/Symbol.ts +29 -0
- package/src/SynchronizedRef.ts +270 -0
- package/src/TArray.ts +495 -0
- package/src/TDeferred.ts +100 -0
- package/src/TMap.ts +515 -0
- package/src/TPriorityQueue.ts +223 -0
- package/src/TPubSub.ts +200 -0
- package/src/TQueue.ts +432 -0
- package/src/TRandom.ts +129 -0
- package/src/TReentrantLock.ts +224 -0
- package/src/TRef.ts +178 -0
- package/src/TSemaphore.ts +129 -0
- package/src/TSet.ts +365 -0
- package/src/TSubscriptionRef.ts +192 -0
- package/src/Take.ts +258 -0
- package/src/TestAnnotation.ts +158 -0
- package/src/TestAnnotationMap.ts +119 -0
- package/src/TestAnnotations.ts +117 -0
- package/src/TestClock.ts +556 -0
- package/src/TestConfig.ts +47 -0
- package/src/TestContext.ts +36 -0
- package/src/TestLive.ts +53 -0
- package/src/TestServices.ts +390 -0
- package/src/TestSized.ts +55 -0
- package/src/Tracer.ts +182 -0
- package/src/Trie.ts +840 -0
- package/src/Tuple.ts +305 -0
- package/src/Types.ts +353 -0
- package/src/Unify.ts +113 -0
- package/src/UpstreamPullRequest.ts +117 -0
- package/src/UpstreamPullStrategy.ts +121 -0
- package/src/Utils.ts +809 -0
- package/src/index.ts +1568 -0
- package/src/internal/array.ts +8 -0
- package/src/internal/blockedRequests.ts +520 -0
- package/src/internal/cache.ts +733 -0
- package/src/internal/cause.ts +1050 -0
- package/src/internal/channel/channelExecutor.ts +1200 -0
- package/src/internal/channel/channelState.ts +134 -0
- package/src/internal/channel/childExecutorDecision.ts +96 -0
- package/src/internal/channel/continuation.ts +200 -0
- package/src/internal/channel/mergeDecision.ts +113 -0
- package/src/internal/channel/mergeState.ts +120 -0
- package/src/internal/channel/mergeStrategy.ts +72 -0
- package/src/internal/channel/singleProducerAsyncInput.ts +259 -0
- package/src/internal/channel/subexecutor.ts +229 -0
- package/src/internal/channel/upstreamPullRequest.ts +84 -0
- package/src/internal/channel/upstreamPullStrategy.ts +87 -0
- package/src/internal/channel.ts +2603 -0
- package/src/internal/clock.ts +95 -0
- package/src/internal/completedRequestMap.ts +9 -0
- package/src/internal/concurrency.ts +54 -0
- package/src/internal/config.ts +716 -0
- package/src/internal/configError.ts +304 -0
- package/src/internal/configProvider/pathPatch.ts +97 -0
- package/src/internal/configProvider.ts +799 -0
- package/src/internal/console.ts +153 -0
- package/src/internal/context.ts +337 -0
- package/src/internal/core-effect.ts +2293 -0
- package/src/internal/core-stream.ts +998 -0
- package/src/internal/core.ts +3189 -0
- package/src/internal/data.ts +36 -0
- package/src/internal/dataSource.ts +327 -0
- package/src/internal/dateTime.ts +1277 -0
- package/src/internal/defaultServices/console.ts +100 -0
- package/src/internal/defaultServices.ts +163 -0
- package/src/internal/deferred.ts +46 -0
- package/src/internal/differ/chunkPatch.ts +211 -0
- package/src/internal/differ/contextPatch.ts +232 -0
- package/src/internal/differ/hashMapPatch.ts +220 -0
- package/src/internal/differ/hashSetPatch.ts +176 -0
- package/src/internal/differ/orPatch.ts +311 -0
- package/src/internal/differ/readonlyArrayPatch.ts +210 -0
- package/src/internal/differ.ts +200 -0
- package/src/internal/doNotation.ts +80 -0
- package/src/internal/effect/circular.ts +895 -0
- package/src/internal/effectable.ts +131 -0
- package/src/internal/either.ts +110 -0
- package/src/internal/encoding/base64.ts +286 -0
- package/src/internal/encoding/base64Url.ts +29 -0
- package/src/internal/encoding/common.ts +51 -0
- package/src/internal/encoding/hex.ts +315 -0
- package/src/internal/errors.ts +7 -0
- package/src/internal/executionPlan.ts +114 -0
- package/src/internal/executionStrategy.ts +74 -0
- package/src/internal/fiber.ts +388 -0
- package/src/internal/fiberId.ts +267 -0
- package/src/internal/fiberMessage.ts +82 -0
- package/src/internal/fiberRefs/patch.ts +144 -0
- package/src/internal/fiberRefs.ts +297 -0
- package/src/internal/fiberRuntime.ts +3842 -0
- package/src/internal/fiberScope.ts +71 -0
- package/src/internal/fiberStatus.ts +119 -0
- package/src/internal/groupBy.ts +530 -0
- package/src/internal/hashMap/array.ts +49 -0
- package/src/internal/hashMap/bitwise.ts +32 -0
- package/src/internal/hashMap/config.ts +14 -0
- package/src/internal/hashMap/keySet.ts +8 -0
- package/src/internal/hashMap/node.ts +391 -0
- package/src/internal/hashMap.ts +586 -0
- package/src/internal/hashSet.ts +323 -0
- package/src/internal/keyedPool.ts +244 -0
- package/src/internal/layer/circular.ts +214 -0
- package/src/internal/layer.ts +1483 -0
- package/src/internal/logSpan.ts +20 -0
- package/src/internal/logger-circular.ts +24 -0
- package/src/internal/logger.ts +522 -0
- package/src/internal/mailbox.ts +561 -0
- package/src/internal/managedRuntime/circular.ts +6 -0
- package/src/internal/managedRuntime.ts +134 -0
- package/src/internal/matcher.ts +652 -0
- package/src/internal/metric/boundaries.ts +75 -0
- package/src/internal/metric/hook.ts +483 -0
- package/src/internal/metric/key.ts +167 -0
- package/src/internal/metric/keyType.ts +238 -0
- package/src/internal/metric/label.ts +41 -0
- package/src/internal/metric/pair.ts +48 -0
- package/src/internal/metric/polling.ts +149 -0
- package/src/internal/metric/registry.ts +187 -0
- package/src/internal/metric/state.ts +290 -0
- package/src/internal/metric.ts +577 -0
- package/src/internal/opCodes/cause.ts +35 -0
- package/src/internal/opCodes/channel.ts +83 -0
- package/src/internal/opCodes/channelChildExecutorDecision.ts +17 -0
- package/src/internal/opCodes/channelMergeDecision.ts +11 -0
- package/src/internal/opCodes/channelMergeState.ts +17 -0
- package/src/internal/opCodes/channelMergeStrategy.ts +11 -0
- package/src/internal/opCodes/channelState.ts +23 -0
- package/src/internal/opCodes/channelUpstreamPullRequest.ts +11 -0
- package/src/internal/opCodes/channelUpstreamPullStrategy.ts +11 -0
- package/src/internal/opCodes/config.ts +65 -0
- package/src/internal/opCodes/configError.ts +35 -0
- package/src/internal/opCodes/continuation.ts +11 -0
- package/src/internal/opCodes/deferred.ts +11 -0
- package/src/internal/opCodes/effect.ts +89 -0
- package/src/internal/opCodes/layer.ts +59 -0
- package/src/internal/opCodes/streamHaltStrategy.ts +23 -0
- package/src/internal/option.ts +80 -0
- package/src/internal/pool.ts +432 -0
- package/src/internal/pubsub.ts +1762 -0
- package/src/internal/query.ts +204 -0
- package/src/internal/queue.ts +766 -0
- package/src/internal/random.ts +161 -0
- package/src/internal/rateLimiter.ts +93 -0
- package/src/internal/rcMap.ts +285 -0
- package/src/internal/rcRef.ts +192 -0
- package/src/internal/redBlackTree/iterator.ts +200 -0
- package/src/internal/redBlackTree/node.ts +68 -0
- package/src/internal/redBlackTree.ts +1245 -0
- package/src/internal/redacted.ts +73 -0
- package/src/internal/ref.ts +171 -0
- package/src/internal/reloadable.ts +140 -0
- package/src/internal/request.ts +177 -0
- package/src/internal/resource.ts +76 -0
- package/src/internal/ringBuffer.ts +68 -0
- package/src/internal/runtime.ts +558 -0
- package/src/internal/runtimeFlags.ts +178 -0
- package/src/internal/runtimeFlagsPatch.ts +103 -0
- package/src/internal/schedule/decision.ts +47 -0
- package/src/internal/schedule/interval.ts +101 -0
- package/src/internal/schedule/intervals.ts +180 -0
- package/src/internal/schedule.ts +2199 -0
- package/src/internal/schema/errors.ts +191 -0
- package/src/internal/schema/schemaId.ts +106 -0
- package/src/internal/schema/util.ts +50 -0
- package/src/internal/scopedCache.ts +644 -0
- package/src/internal/scopedRef.ts +118 -0
- package/src/internal/secret.ts +89 -0
- package/src/internal/singleShotGen.ts +35 -0
- package/src/internal/sink.ts +2120 -0
- package/src/internal/stack.ts +10 -0
- package/src/internal/stm/core.ts +817 -0
- package/src/internal/stm/entry.ts +59 -0
- package/src/internal/stm/journal.ts +123 -0
- package/src/internal/stm/opCodes/stm.ts +71 -0
- package/src/internal/stm/opCodes/stmState.ts +17 -0
- package/src/internal/stm/opCodes/strategy.ts +17 -0
- package/src/internal/stm/opCodes/tExit.ts +29 -0
- package/src/internal/stm/opCodes/tryCommit.ts +11 -0
- package/src/internal/stm/stm.ts +1453 -0
- package/src/internal/stm/stmState.ts +136 -0
- package/src/internal/stm/tArray.ts +550 -0
- package/src/internal/stm/tDeferred.ts +81 -0
- package/src/internal/stm/tExit.ts +190 -0
- package/src/internal/stm/tMap.ts +824 -0
- package/src/internal/stm/tPriorityQueue.ts +267 -0
- package/src/internal/stm/tPubSub.ts +551 -0
- package/src/internal/stm/tQueue.ts +393 -0
- package/src/internal/stm/tRandom.ts +140 -0
- package/src/internal/stm/tReentrantLock.ts +352 -0
- package/src/internal/stm/tRef.ts +195 -0
- package/src/internal/stm/tSemaphore.ts +113 -0
- package/src/internal/stm/tSet.ts +259 -0
- package/src/internal/stm/tSubscriptionRef.ts +286 -0
- package/src/internal/stm/tryCommit.ts +34 -0
- package/src/internal/stm/txnId.ts +14 -0
- package/src/internal/stm/versioned.ts +4 -0
- package/src/internal/stream/debounceState.ts +57 -0
- package/src/internal/stream/emit.ts +123 -0
- package/src/internal/stream/haltStrategy.ts +94 -0
- package/src/internal/stream/handoff.ts +187 -0
- package/src/internal/stream/handoffSignal.ts +59 -0
- package/src/internal/stream/pull.ts +34 -0
- package/src/internal/stream/sinkEndReason.ts +30 -0
- package/src/internal/stream/zipAllState.ts +88 -0
- package/src/internal/stream/zipChunksState.ts +56 -0
- package/src/internal/stream.ts +8801 -0
- package/src/internal/string-utils.ts +107 -0
- package/src/internal/subscriptionRef.ts +138 -0
- package/src/internal/supervisor/patch.ts +190 -0
- package/src/internal/supervisor.ts +303 -0
- package/src/internal/synchronizedRef.ts +114 -0
- package/src/internal/take.ts +199 -0
- package/src/internal/testing/sleep.ts +27 -0
- package/src/internal/testing/suspendedWarningData.ts +85 -0
- package/src/internal/testing/warningData.ts +94 -0
- package/src/internal/tracer.ts +150 -0
- package/src/internal/trie.ts +722 -0
- package/src/internal/version.ts +7 -0
package/src/Iterable.ts
ADDED
|
@@ -0,0 +1,1119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This module provides utility functions for working with Iterables in TypeScript.
|
|
3
|
+
*
|
|
4
|
+
* @since 2.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { NonEmptyArray } from "./Array.js"
|
|
8
|
+
import type { Either } from "./Either.js"
|
|
9
|
+
import * as E from "./Either.js"
|
|
10
|
+
import * as Equal from "./Equal.js"
|
|
11
|
+
import { dual, identity } from "./Function.js"
|
|
12
|
+
import type { Option } from "./Option.js"
|
|
13
|
+
import * as O from "./Option.js"
|
|
14
|
+
import { isBoolean } from "./Predicate.js"
|
|
15
|
+
import type * as Record from "./Record.js"
|
|
16
|
+
import * as Tuple from "./Tuple.js"
|
|
17
|
+
import type { NoInfer } from "./Types.js"
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Return a `Iterable` with element `i` initialized with `f(i)`.
|
|
21
|
+
*
|
|
22
|
+
* If the `length` is not specified, the `Iterable` will be infinite.
|
|
23
|
+
*
|
|
24
|
+
* **Note**. `length` is normalized to an integer >= 1.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* import * as assert from "node:assert"
|
|
29
|
+
* import { makeBy } from "effect/Iterable"
|
|
30
|
+
*
|
|
31
|
+
* assert.deepStrictEqual(Array.from(makeBy(n => n * 2, { length: 5 })), [0, 2, 4, 6, 8])
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @category constructors
|
|
35
|
+
* @since 2.0.0
|
|
36
|
+
*/
|
|
37
|
+
export const makeBy = <A>(f: (i: number) => A, options?: {
|
|
38
|
+
readonly length?: number
|
|
39
|
+
}): Iterable<A> => {
|
|
40
|
+
const max = options?.length !== undefined ? Math.max(1, Math.floor(options.length)) : Infinity
|
|
41
|
+
return {
|
|
42
|
+
[Symbol.iterator]() {
|
|
43
|
+
let i = 0
|
|
44
|
+
return {
|
|
45
|
+
next(): IteratorResult<A> {
|
|
46
|
+
if (i < max) {
|
|
47
|
+
return { value: f(i++), done: false }
|
|
48
|
+
}
|
|
49
|
+
return { done: true, value: undefined }
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Return a `Iterable` containing a range of integers, including both endpoints.
|
|
58
|
+
*
|
|
59
|
+
* If `end` is omitted, the range will not have an upper bound.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* import * as assert from "node:assert"
|
|
64
|
+
* import { range } from "effect/Iterable"
|
|
65
|
+
*
|
|
66
|
+
* assert.deepStrictEqual(Array.from(range(1, 3)), [1, 2, 3])
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* @category constructors
|
|
70
|
+
* @since 2.0.0
|
|
71
|
+
*/
|
|
72
|
+
export const range = (start: number, end?: number): Iterable<number> => {
|
|
73
|
+
if (end === undefined) {
|
|
74
|
+
return makeBy((i) => start + i)
|
|
75
|
+
}
|
|
76
|
+
return makeBy((i) => start + i, {
|
|
77
|
+
length: start <= end ? end - start + 1 : 1
|
|
78
|
+
})
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Return a `Iterable` containing a value repeated the specified number of times.
|
|
83
|
+
*
|
|
84
|
+
* **Note**. `n` is normalized to an integer >= 1.
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```ts
|
|
88
|
+
* import * as assert from "node:assert"
|
|
89
|
+
* import { replicate } from "effect/Iterable"
|
|
90
|
+
*
|
|
91
|
+
* assert.deepStrictEqual(Array.from(replicate("a", 3)), ["a", "a", "a"])
|
|
92
|
+
* ```
|
|
93
|
+
*
|
|
94
|
+
* @category constructors
|
|
95
|
+
* @since 2.0.0
|
|
96
|
+
*/
|
|
97
|
+
export const replicate: {
|
|
98
|
+
(n: number): <A>(a: A) => Iterable<A>
|
|
99
|
+
<A>(a: A, n: number): Iterable<A>
|
|
100
|
+
} = dual(2, <A>(a: A, n: number): Iterable<A> => makeBy(() => a, { length: n }))
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Takes a record and returns an Iterable of tuples containing its keys and values.
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```ts
|
|
107
|
+
* import * as assert from "node:assert"
|
|
108
|
+
* import { fromRecord } from "effect/Iterable"
|
|
109
|
+
*
|
|
110
|
+
* const x = { a: 1, b: 2, c: 3 }
|
|
111
|
+
* assert.deepStrictEqual(Array.from(fromRecord(x)), [["a", 1], ["b", 2], ["c", 3]])
|
|
112
|
+
* ```
|
|
113
|
+
*
|
|
114
|
+
* @category conversions
|
|
115
|
+
* @since 2.0.0
|
|
116
|
+
*/
|
|
117
|
+
export const fromRecord = <K extends string, A>(self: Readonly<Record<K, A>>): Iterable<[K, A]> => ({
|
|
118
|
+
*[Symbol.iterator]() {
|
|
119
|
+
for (const key in self) {
|
|
120
|
+
if (Object.prototype.hasOwnProperty.call(self, key)) {
|
|
121
|
+
yield [key, self[key]]
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Prepend an element to the front of an `Iterable`, creating a new `Iterable`.
|
|
129
|
+
*
|
|
130
|
+
* @category concatenating
|
|
131
|
+
* @since 2.0.0
|
|
132
|
+
*/
|
|
133
|
+
export const prepend: {
|
|
134
|
+
<B>(head: B): <A>(self: Iterable<A>) => Iterable<A | B>
|
|
135
|
+
<A, B>(self: Iterable<A>, head: B): Iterable<A | B>
|
|
136
|
+
} = dual(2, <A, B>(self: Iterable<A>, head: B): Iterable<A | B> => prependAll(self, [head]))
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Prepends the specified prefix iterable to the beginning of the specified iterable.
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```ts
|
|
143
|
+
* import * as assert from "node:assert"
|
|
144
|
+
* import { Iterable } from "effect"
|
|
145
|
+
*
|
|
146
|
+
* assert.deepStrictEqual(
|
|
147
|
+
* Array.from(Iterable.prependAll([1, 2], ["a", "b"])),
|
|
148
|
+
* ["a", "b", 1, 2]
|
|
149
|
+
* )
|
|
150
|
+
* ```
|
|
151
|
+
*
|
|
152
|
+
* @category concatenating
|
|
153
|
+
* @since 2.0.0
|
|
154
|
+
*/
|
|
155
|
+
export const prependAll: {
|
|
156
|
+
<B>(that: Iterable<B>): <A>(self: Iterable<A>) => Iterable<A | B>
|
|
157
|
+
<A, B>(self: Iterable<A>, that: Iterable<B>): Iterable<A | B>
|
|
158
|
+
} = dual(
|
|
159
|
+
2,
|
|
160
|
+
<A, B>(self: Iterable<A>, that: Iterable<B>): Iterable<A | B> => appendAll(that, self)
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Append an element to the end of an `Iterable`, creating a new `Iterable`.
|
|
165
|
+
*
|
|
166
|
+
* @category concatenating
|
|
167
|
+
* @since 2.0.0
|
|
168
|
+
*/
|
|
169
|
+
export const append: {
|
|
170
|
+
<B>(last: B): <A>(self: Iterable<A>) => Iterable<A | B>
|
|
171
|
+
<A, B>(self: Iterable<A>, last: B): Iterable<A | B>
|
|
172
|
+
} = dual(2, <A, B>(self: Iterable<A>, last: B): Iterable<A | B> => appendAll(self, [last]))
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Concatenates two iterables, combining their elements.
|
|
176
|
+
*
|
|
177
|
+
* @category concatenating
|
|
178
|
+
* @since 2.0.0
|
|
179
|
+
*/
|
|
180
|
+
export const appendAll: {
|
|
181
|
+
<B>(that: Iterable<B>): <A>(self: Iterable<A>) => Iterable<A | B>
|
|
182
|
+
<A, B>(self: Iterable<A>, that: Iterable<B>): Iterable<A | B>
|
|
183
|
+
} = dual(
|
|
184
|
+
2,
|
|
185
|
+
<A, B>(self: Iterable<A>, that: Iterable<B>): Iterable<A | B> => ({
|
|
186
|
+
[Symbol.iterator]() {
|
|
187
|
+
const iterA = self[Symbol.iterator]()
|
|
188
|
+
let doneA = false
|
|
189
|
+
let iterB: Iterator<B>
|
|
190
|
+
return {
|
|
191
|
+
next() {
|
|
192
|
+
if (!doneA) {
|
|
193
|
+
const r = iterA.next()
|
|
194
|
+
if (r.done) {
|
|
195
|
+
doneA = true
|
|
196
|
+
iterB = that[Symbol.iterator]()
|
|
197
|
+
return iterB.next()
|
|
198
|
+
}
|
|
199
|
+
return r
|
|
200
|
+
}
|
|
201
|
+
return iterB.next()
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
})
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Reduce an `Iterable` from the left, keeping all intermediate results instead of only the final result.
|
|
210
|
+
*
|
|
211
|
+
* @category folding
|
|
212
|
+
* @since 2.0.0
|
|
213
|
+
*/
|
|
214
|
+
export const scan: {
|
|
215
|
+
<B, A>(b: B, f: (b: B, a: A) => B): (self: Iterable<A>) => Iterable<B>
|
|
216
|
+
<A, B>(self: Iterable<A>, b: B, f: (b: B, a: A) => B): Iterable<B>
|
|
217
|
+
} = dual(3, <A, B>(self: Iterable<A>, b: B, f: (b: B, a: A) => B): Iterable<B> => ({
|
|
218
|
+
[Symbol.iterator]() {
|
|
219
|
+
let acc = b
|
|
220
|
+
let iterator: Iterator<A> | undefined
|
|
221
|
+
function next() {
|
|
222
|
+
if (iterator === undefined) {
|
|
223
|
+
iterator = self[Symbol.iterator]()
|
|
224
|
+
return { done: false, value: acc }
|
|
225
|
+
}
|
|
226
|
+
const result = iterator.next()
|
|
227
|
+
if (result.done) {
|
|
228
|
+
return result
|
|
229
|
+
}
|
|
230
|
+
acc = f(acc, result.value)
|
|
231
|
+
return { done: false, value: acc }
|
|
232
|
+
}
|
|
233
|
+
return { next }
|
|
234
|
+
}
|
|
235
|
+
}))
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Determine if an `Iterable` is empty
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* ```ts
|
|
242
|
+
* import * as assert from "node:assert"
|
|
243
|
+
* import { isEmpty } from "effect/Iterable"
|
|
244
|
+
*
|
|
245
|
+
* assert.deepStrictEqual(isEmpty([]), true);
|
|
246
|
+
* assert.deepStrictEqual(isEmpty([1, 2, 3]), false);
|
|
247
|
+
* ```
|
|
248
|
+
*
|
|
249
|
+
* @category guards
|
|
250
|
+
* @since 2.0.0
|
|
251
|
+
*/
|
|
252
|
+
export const isEmpty = <A>(self: Iterable<A>): self is Iterable<never> => {
|
|
253
|
+
const iterator = self[Symbol.iterator]()
|
|
254
|
+
return iterator.next().done === true
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Return the number of elements in a `Iterable`.
|
|
259
|
+
*
|
|
260
|
+
* @category getters
|
|
261
|
+
* @since 2.0.0
|
|
262
|
+
*/
|
|
263
|
+
export const size = <A>(self: Iterable<A>): number => {
|
|
264
|
+
const iterator = self[Symbol.iterator]()
|
|
265
|
+
let count = 0
|
|
266
|
+
while (!iterator.next().done) {
|
|
267
|
+
count++
|
|
268
|
+
}
|
|
269
|
+
return count
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Get the first element of a `Iterable`, or `None` if the `Iterable` is empty.
|
|
274
|
+
*
|
|
275
|
+
* @category getters
|
|
276
|
+
* @since 2.0.0
|
|
277
|
+
*/
|
|
278
|
+
export const head = <A>(self: Iterable<A>): Option<A> => {
|
|
279
|
+
const iterator = self[Symbol.iterator]()
|
|
280
|
+
const result = iterator.next()
|
|
281
|
+
return result.done ? O.none() : O.some(result.value)
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Get the first element of a `Iterable`, or throw an error if the `Iterable` is empty.
|
|
286
|
+
*
|
|
287
|
+
* @category getters
|
|
288
|
+
* @since 3.3.0
|
|
289
|
+
*/
|
|
290
|
+
export const unsafeHead = <A>(self: Iterable<A>): A => {
|
|
291
|
+
const iterator = self[Symbol.iterator]()
|
|
292
|
+
const result = iterator.next()
|
|
293
|
+
if (result.done) throw new Error("unsafeHead: empty iterable")
|
|
294
|
+
return result.value
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Keep only a max number of elements from the start of an `Iterable`, creating a new `Iterable`.
|
|
299
|
+
*
|
|
300
|
+
* **Note**. `n` is normalized to a non negative integer.
|
|
301
|
+
*
|
|
302
|
+
* @category getters
|
|
303
|
+
* @since 2.0.0
|
|
304
|
+
*/
|
|
305
|
+
export const take: {
|
|
306
|
+
(n: number): <A>(self: Iterable<A>) => Iterable<A>
|
|
307
|
+
<A>(self: Iterable<A>, n: number): Iterable<A>
|
|
308
|
+
} = dual(2, <A>(self: Iterable<A>, n: number): Iterable<A> => ({
|
|
309
|
+
[Symbol.iterator]() {
|
|
310
|
+
let i = 0
|
|
311
|
+
const iterator = self[Symbol.iterator]()
|
|
312
|
+
return {
|
|
313
|
+
next() {
|
|
314
|
+
if (i < n) {
|
|
315
|
+
i++
|
|
316
|
+
return iterator.next()
|
|
317
|
+
}
|
|
318
|
+
return { done: true, value: undefined }
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}))
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Calculate the longest initial Iterable for which all element satisfy the specified predicate, creating a new `Iterable`.
|
|
326
|
+
*
|
|
327
|
+
* @category getters
|
|
328
|
+
* @since 2.0.0
|
|
329
|
+
*/
|
|
330
|
+
export const takeWhile: {
|
|
331
|
+
<A, B extends A>(refinement: (a: NoInfer<A>, i: number) => a is B): (self: Iterable<A>) => Iterable<B>
|
|
332
|
+
<A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Iterable<A>
|
|
333
|
+
<A, B extends A>(self: Iterable<A>, refinement: (a: A, i: number) => a is B): Iterable<B>
|
|
334
|
+
<A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Iterable<A>
|
|
335
|
+
} = dual(2, <A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Iterable<A> => ({
|
|
336
|
+
[Symbol.iterator]() {
|
|
337
|
+
const iterator = self[Symbol.iterator]()
|
|
338
|
+
let i = 0
|
|
339
|
+
return {
|
|
340
|
+
next() {
|
|
341
|
+
const result = iterator.next()
|
|
342
|
+
if (result.done || !predicate(result.value, i++)) {
|
|
343
|
+
return { done: true, value: undefined }
|
|
344
|
+
}
|
|
345
|
+
return result
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}))
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Drop a max number of elements from the start of an `Iterable`
|
|
353
|
+
*
|
|
354
|
+
* **Note**. `n` is normalized to a non negative integer.
|
|
355
|
+
*
|
|
356
|
+
* @category getters
|
|
357
|
+
* @since 2.0.0
|
|
358
|
+
*/
|
|
359
|
+
export const drop: {
|
|
360
|
+
(n: number): <A>(self: Iterable<A>) => Iterable<A>
|
|
361
|
+
<A>(self: Iterable<A>, n: number): Iterable<A>
|
|
362
|
+
} = dual(2, <A>(self: Iterable<A>, n: number): Iterable<A> => ({
|
|
363
|
+
[Symbol.iterator]() {
|
|
364
|
+
const iterator = self[Symbol.iterator]()
|
|
365
|
+
let i = 0
|
|
366
|
+
return {
|
|
367
|
+
next() {
|
|
368
|
+
while (i < n) {
|
|
369
|
+
const result = iterator.next()
|
|
370
|
+
if (result.done) {
|
|
371
|
+
return { done: true, value: undefined }
|
|
372
|
+
}
|
|
373
|
+
i++
|
|
374
|
+
}
|
|
375
|
+
return iterator.next()
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}))
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Returns the first element that satisfies the specified
|
|
383
|
+
* predicate, or `None` if no such element exists.
|
|
384
|
+
*
|
|
385
|
+
* @category elements
|
|
386
|
+
* @since 2.0.0
|
|
387
|
+
*/
|
|
388
|
+
export const findFirst: {
|
|
389
|
+
<A, B>(f: (a: NoInfer<A>, i: number) => Option<B>): (self: Iterable<A>) => Option<B>
|
|
390
|
+
<A, B extends A>(refinement: (a: NoInfer<A>, i: number) => a is B): (self: Iterable<A>) => Option<B>
|
|
391
|
+
<A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Option<A>
|
|
392
|
+
<A, B>(self: Iterable<A>, f: (a: A, i: number) => Option<B>): Option<B>
|
|
393
|
+
<A, B extends A>(self: Iterable<A>, refinement: (a: A, i: number) => a is B): Option<B>
|
|
394
|
+
<A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Option<A>
|
|
395
|
+
} = dual(
|
|
396
|
+
2,
|
|
397
|
+
<A>(self: Iterable<A>, f: ((a: A, i: number) => boolean) | ((a: A, i: number) => Option<A>)): Option<A> => {
|
|
398
|
+
let i = 0
|
|
399
|
+
for (const a of self) {
|
|
400
|
+
const o = f(a, i)
|
|
401
|
+
if (isBoolean(o)) {
|
|
402
|
+
if (o) {
|
|
403
|
+
return O.some(a)
|
|
404
|
+
}
|
|
405
|
+
} else {
|
|
406
|
+
if (O.isSome(o)) {
|
|
407
|
+
return o
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
i++
|
|
411
|
+
}
|
|
412
|
+
return O.none()
|
|
413
|
+
}
|
|
414
|
+
)
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Find the last element for which a predicate holds.
|
|
418
|
+
*
|
|
419
|
+
* @category elements
|
|
420
|
+
* @since 2.0.0
|
|
421
|
+
*/
|
|
422
|
+
export const findLast: {
|
|
423
|
+
<A, B>(f: (a: NoInfer<A>, i: number) => Option<B>): (self: Iterable<A>) => Option<B>
|
|
424
|
+
<A, B extends A>(refinement: (a: NoInfer<A>, i: number) => a is B): (self: Iterable<A>) => Option<B>
|
|
425
|
+
<A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Option<A>
|
|
426
|
+
<A, B>(self: Iterable<A>, f: (a: A, i: number) => Option<B>): Option<B>
|
|
427
|
+
<A, B extends A>(self: Iterable<A>, refinement: (a: A, i: number) => a is B): Option<B>
|
|
428
|
+
<A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Option<A>
|
|
429
|
+
} = dual(
|
|
430
|
+
2,
|
|
431
|
+
<A>(self: Iterable<A>, f: ((a: A, i: number) => boolean) | ((a: A, i: number) => Option<A>)): Option<A> => {
|
|
432
|
+
let i = 0
|
|
433
|
+
let last: Option<A> = O.none()
|
|
434
|
+
for (const a of self) {
|
|
435
|
+
const o = f(a, i)
|
|
436
|
+
if (isBoolean(o)) {
|
|
437
|
+
if (o) {
|
|
438
|
+
last = O.some(a)
|
|
439
|
+
}
|
|
440
|
+
} else {
|
|
441
|
+
if (O.isSome(o)) {
|
|
442
|
+
last = o
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
i++
|
|
446
|
+
}
|
|
447
|
+
return last
|
|
448
|
+
}
|
|
449
|
+
)
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Takes two `Iterable`s and returns an `Iterable` of corresponding pairs.
|
|
453
|
+
*
|
|
454
|
+
* @category zipping
|
|
455
|
+
* @since 2.0.0
|
|
456
|
+
*/
|
|
457
|
+
export const zip: {
|
|
458
|
+
<B>(that: Iterable<B>): <A>(self: Iterable<A>) => Iterable<[A, B]>
|
|
459
|
+
<A, B>(self: Iterable<A>, that: Iterable<B>): Iterable<[A, B]>
|
|
460
|
+
} = dual(
|
|
461
|
+
2,
|
|
462
|
+
<A, B>(self: Iterable<A>, that: Iterable<B>): Iterable<[A, B]> => zipWith(self, that, Tuple.make)
|
|
463
|
+
)
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Apply a function to pairs of elements at the same index in two `Iterable`s, collecting the results. If one
|
|
467
|
+
* input `Iterable` is short, excess elements of the longer `Iterable` are discarded.
|
|
468
|
+
*
|
|
469
|
+
* @category zipping
|
|
470
|
+
* @since 2.0.0
|
|
471
|
+
*/
|
|
472
|
+
export const zipWith: {
|
|
473
|
+
<B, A, C>(that: Iterable<B>, f: (a: A, b: B) => C): (self: Iterable<A>) => Iterable<C>
|
|
474
|
+
<A, B, C>(self: Iterable<A>, that: Iterable<B>, f: (a: A, b: B) => C): Iterable<C>
|
|
475
|
+
} = dual(3, <B, A, C>(self: Iterable<A>, that: Iterable<B>, f: (a: A, b: B) => C): Iterable<C> => ({
|
|
476
|
+
[Symbol.iterator]() {
|
|
477
|
+
const selfIterator = self[Symbol.iterator]()
|
|
478
|
+
const thatIterator = that[Symbol.iterator]()
|
|
479
|
+
return {
|
|
480
|
+
next() {
|
|
481
|
+
const selfResult = selfIterator.next()
|
|
482
|
+
const thatResult = thatIterator.next()
|
|
483
|
+
if (selfResult.done || thatResult.done) {
|
|
484
|
+
return { done: true, value: undefined }
|
|
485
|
+
}
|
|
486
|
+
return { done: false, value: f(selfResult.value, thatResult.value) }
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}))
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* Places an element in between members of an `Iterable`.
|
|
494
|
+
* If the input is a non-empty array, the result is also a non-empty array.
|
|
495
|
+
*
|
|
496
|
+
* @since 2.0.0
|
|
497
|
+
*/
|
|
498
|
+
export const intersperse: {
|
|
499
|
+
<B>(middle: B): <A>(self: Iterable<A>) => Iterable<A | B>
|
|
500
|
+
<A, B>(self: Iterable<A>, middle: B): Iterable<A | B>
|
|
501
|
+
} = dual(2, <A, B>(self: Iterable<A>, middle: B): Iterable<A | B> => ({
|
|
502
|
+
[Symbol.iterator]() {
|
|
503
|
+
const iterator = self[Symbol.iterator]()
|
|
504
|
+
let next = iterator.next()
|
|
505
|
+
let emitted = false
|
|
506
|
+
return {
|
|
507
|
+
next() {
|
|
508
|
+
if (next.done) {
|
|
509
|
+
return next
|
|
510
|
+
} else if (emitted) {
|
|
511
|
+
emitted = false
|
|
512
|
+
return { done: false, value: middle }
|
|
513
|
+
}
|
|
514
|
+
emitted = true
|
|
515
|
+
const result = next
|
|
516
|
+
next = iterator.next()
|
|
517
|
+
return result
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}))
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* Returns a function that checks if an `Iterable` contains a given value using a provided `isEquivalent` function.
|
|
525
|
+
*
|
|
526
|
+
* @category elements
|
|
527
|
+
* @since 2.0.0
|
|
528
|
+
*/
|
|
529
|
+
export const containsWith = <A>(isEquivalent: (self: A, that: A) => boolean): {
|
|
530
|
+
(a: A): (self: Iterable<A>) => boolean
|
|
531
|
+
(self: Iterable<A>, a: A): boolean
|
|
532
|
+
} =>
|
|
533
|
+
dual(2, (self: Iterable<A>, a: A): boolean => {
|
|
534
|
+
for (const i of self) {
|
|
535
|
+
if (isEquivalent(a, i)) {
|
|
536
|
+
return true
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
return false
|
|
540
|
+
})
|
|
541
|
+
|
|
542
|
+
const _equivalence = Equal.equivalence()
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* Returns a function that checks if a `Iterable` contains a given value using the default `Equivalence`.
|
|
546
|
+
*
|
|
547
|
+
* @category elements
|
|
548
|
+
* @since 2.0.0
|
|
549
|
+
*/
|
|
550
|
+
export const contains: {
|
|
551
|
+
<A>(a: A): (self: Iterable<A>) => boolean
|
|
552
|
+
<A>(self: Iterable<A>, a: A): boolean
|
|
553
|
+
} = containsWith(_equivalence)
|
|
554
|
+
|
|
555
|
+
/**
|
|
556
|
+
* Splits an `Iterable` into length-`n` pieces. The last piece will be shorter if `n` does not evenly divide the length of
|
|
557
|
+
* the `Iterable`.
|
|
558
|
+
*
|
|
559
|
+
* @category splitting
|
|
560
|
+
* @since 2.0.0
|
|
561
|
+
*/
|
|
562
|
+
export const chunksOf: {
|
|
563
|
+
(n: number): <A>(self: Iterable<A>) => Iterable<Array<A>>
|
|
564
|
+
<A>(self: Iterable<A>, n: number): Iterable<Array<A>>
|
|
565
|
+
} = dual(2, <A>(self: Iterable<A>, n: number): Iterable<Array<A>> => {
|
|
566
|
+
const safeN = Math.max(1, Math.floor(n))
|
|
567
|
+
return ({
|
|
568
|
+
[Symbol.iterator]() {
|
|
569
|
+
let iterator: Iterator<A> | undefined = self[Symbol.iterator]()
|
|
570
|
+
return {
|
|
571
|
+
next() {
|
|
572
|
+
if (iterator === undefined) {
|
|
573
|
+
return { done: true, value: undefined }
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
const chunk: Array<A> = []
|
|
577
|
+
for (let i = 0; i < safeN; i++) {
|
|
578
|
+
const result = iterator.next()
|
|
579
|
+
if (result.done) {
|
|
580
|
+
iterator = undefined
|
|
581
|
+
return chunk.length === 0 ? { done: true, value: undefined } : { done: false, value: chunk }
|
|
582
|
+
}
|
|
583
|
+
chunk.push(result.value)
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
return { done: false, value: chunk }
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
})
|
|
591
|
+
})
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* Group equal, consecutive elements of an `Iterable` into `NonEmptyArray`s using the provided `isEquivalent` function.
|
|
595
|
+
*
|
|
596
|
+
* @category grouping
|
|
597
|
+
* @since 2.0.0
|
|
598
|
+
*/
|
|
599
|
+
export const groupWith: {
|
|
600
|
+
<A>(isEquivalent: (self: A, that: A) => boolean): (self: Iterable<A>) => Iterable<NonEmptyArray<A>>
|
|
601
|
+
<A>(self: Iterable<A>, isEquivalent: (self: A, that: A) => boolean): Iterable<NonEmptyArray<A>>
|
|
602
|
+
} = dual(
|
|
603
|
+
2,
|
|
604
|
+
<A>(self: Iterable<A>, isEquivalent: (self: A, that: A) => boolean): Iterable<NonEmptyArray<A>> => ({
|
|
605
|
+
[Symbol.iterator]() {
|
|
606
|
+
const iterator = self[Symbol.iterator]()
|
|
607
|
+
let nextResult: IteratorResult<A> | undefined
|
|
608
|
+
return {
|
|
609
|
+
next() {
|
|
610
|
+
let result: IteratorResult<A>
|
|
611
|
+
if (nextResult !== undefined) {
|
|
612
|
+
if (nextResult.done) {
|
|
613
|
+
return { done: true, value: undefined }
|
|
614
|
+
}
|
|
615
|
+
result = nextResult
|
|
616
|
+
nextResult = undefined
|
|
617
|
+
} else {
|
|
618
|
+
result = iterator.next()
|
|
619
|
+
if (result.done) {
|
|
620
|
+
return { done: true, value: undefined }
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
const chunk: NonEmptyArray<A> = [result.value]
|
|
624
|
+
|
|
625
|
+
while (true) {
|
|
626
|
+
const next = iterator.next()
|
|
627
|
+
if (next.done || !isEquivalent(result.value, next.value)) {
|
|
628
|
+
nextResult = next
|
|
629
|
+
return { done: false, value: chunk }
|
|
630
|
+
}
|
|
631
|
+
chunk.push(next.value)
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
})
|
|
637
|
+
)
|
|
638
|
+
|
|
639
|
+
/**
|
|
640
|
+
* Group equal, consecutive elements of an `Iterable` into `NonEmptyArray`s.
|
|
641
|
+
*
|
|
642
|
+
* @category grouping
|
|
643
|
+
* @since 2.0.0
|
|
644
|
+
*/
|
|
645
|
+
export const group: <A>(self: Iterable<A>) => Iterable<NonEmptyArray<A>> = groupWith(
|
|
646
|
+
Equal.equivalence()
|
|
647
|
+
)
|
|
648
|
+
|
|
649
|
+
/**
|
|
650
|
+
* Splits an `Iterable` into sub-non-empty-arrays stored in an object, based on the result of calling a `string`-returning
|
|
651
|
+
* function on each element, and grouping the results according to values returned
|
|
652
|
+
*
|
|
653
|
+
* @category grouping
|
|
654
|
+
* @since 2.0.0
|
|
655
|
+
*/
|
|
656
|
+
export const groupBy: {
|
|
657
|
+
<A, K extends string | symbol>(
|
|
658
|
+
f: (a: A) => K
|
|
659
|
+
): (self: Iterable<A>) => Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>
|
|
660
|
+
<A, K extends string | symbol>(
|
|
661
|
+
self: Iterable<A>,
|
|
662
|
+
f: (a: A) => K
|
|
663
|
+
): Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>
|
|
664
|
+
} = dual(2, <A, K extends string | symbol>(
|
|
665
|
+
self: Iterable<A>,
|
|
666
|
+
f: (a: A) => K
|
|
667
|
+
): Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>> => {
|
|
668
|
+
const out: Record<string | symbol, NonEmptyArray<A>> = {}
|
|
669
|
+
for (const a of self) {
|
|
670
|
+
const k = f(a)
|
|
671
|
+
if (Object.prototype.hasOwnProperty.call(out, k)) {
|
|
672
|
+
out[k].push(a)
|
|
673
|
+
} else {
|
|
674
|
+
out[k] = [a]
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
return out
|
|
678
|
+
})
|
|
679
|
+
|
|
680
|
+
const constEmpty: Iterable<never> = {
|
|
681
|
+
[Symbol.iterator]() {
|
|
682
|
+
return constEmptyIterator
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
const constEmptyIterator: Iterator<never> = {
|
|
686
|
+
next() {
|
|
687
|
+
return { done: true, value: undefined }
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
/**
|
|
692
|
+
* @category constructors
|
|
693
|
+
* @since 2.0.0
|
|
694
|
+
*/
|
|
695
|
+
export const empty = <A = never>(): Iterable<A> => constEmpty
|
|
696
|
+
|
|
697
|
+
/**
|
|
698
|
+
* Constructs a new `Iterable<A>` from the specified value.
|
|
699
|
+
*
|
|
700
|
+
* @category constructors
|
|
701
|
+
* @since 2.0.0
|
|
702
|
+
*/
|
|
703
|
+
export const of = <A>(a: A): Iterable<A> => [a]
|
|
704
|
+
|
|
705
|
+
/**
|
|
706
|
+
* @category mapping
|
|
707
|
+
* @since 2.0.0
|
|
708
|
+
*/
|
|
709
|
+
export const map: {
|
|
710
|
+
<A, B>(
|
|
711
|
+
f: (a: NoInfer<A>, i: number) => B
|
|
712
|
+
): (self: Iterable<A>) => Iterable<B>
|
|
713
|
+
<A, B>(self: Iterable<A>, f: (a: NoInfer<A>, i: number) => B): Iterable<B>
|
|
714
|
+
} = dual(2, <A, B>(self: Iterable<A>, f: (a: A, i: number) => B): Iterable<B> => ({
|
|
715
|
+
[Symbol.iterator]() {
|
|
716
|
+
const iterator = self[Symbol.iterator]()
|
|
717
|
+
let i = 0
|
|
718
|
+
return {
|
|
719
|
+
next() {
|
|
720
|
+
const result = iterator.next()
|
|
721
|
+
if (result.done) {
|
|
722
|
+
return { done: true, value: undefined }
|
|
723
|
+
}
|
|
724
|
+
return { done: false, value: f(result.value, i++) }
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
}))
|
|
729
|
+
|
|
730
|
+
/**
|
|
731
|
+
* Applies a function to each element in an Iterable and returns a new Iterable containing the concatenated mapped elements.
|
|
732
|
+
*
|
|
733
|
+
* @category sequencing
|
|
734
|
+
* @since 2.0.0
|
|
735
|
+
*/
|
|
736
|
+
export const flatMap: {
|
|
737
|
+
<A, B>(
|
|
738
|
+
f: (a: NoInfer<A>, i: number) => Iterable<B>
|
|
739
|
+
): (self: Iterable<A>) => Iterable<B>
|
|
740
|
+
<A, B>(self: Iterable<A>, f: (a: NoInfer<A>, i: number) => Iterable<B>): Iterable<B>
|
|
741
|
+
} = dual(
|
|
742
|
+
2,
|
|
743
|
+
<A, B>(self: Iterable<A>, f: (a: A, i: number) => Iterable<B>): Iterable<B> => flatten(map(self, f))
|
|
744
|
+
)
|
|
745
|
+
|
|
746
|
+
/**
|
|
747
|
+
* Flattens an Iterable of Iterables into a single Iterable
|
|
748
|
+
*
|
|
749
|
+
* @category sequencing
|
|
750
|
+
* @since 2.0.0
|
|
751
|
+
*/
|
|
752
|
+
export const flatten = <A>(self: Iterable<Iterable<A>>): Iterable<A> => ({
|
|
753
|
+
[Symbol.iterator]() {
|
|
754
|
+
const outerIterator = self[Symbol.iterator]()
|
|
755
|
+
let innerIterator: Iterator<A> | undefined
|
|
756
|
+
function next() {
|
|
757
|
+
if (innerIterator === undefined) {
|
|
758
|
+
const next = outerIterator.next()
|
|
759
|
+
if (next.done) {
|
|
760
|
+
return next
|
|
761
|
+
}
|
|
762
|
+
innerIterator = next.value[Symbol.iterator]()
|
|
763
|
+
}
|
|
764
|
+
const result = innerIterator.next()
|
|
765
|
+
if (result.done) {
|
|
766
|
+
innerIterator = undefined
|
|
767
|
+
return next()
|
|
768
|
+
}
|
|
769
|
+
return result
|
|
770
|
+
}
|
|
771
|
+
return { next }
|
|
772
|
+
}
|
|
773
|
+
})
|
|
774
|
+
|
|
775
|
+
/**
|
|
776
|
+
* @category filtering
|
|
777
|
+
* @since 2.0.0
|
|
778
|
+
*/
|
|
779
|
+
export const filterMap: {
|
|
780
|
+
<A, B>(f: (a: A, i: number) => Option<B>): (self: Iterable<A>) => Iterable<B>
|
|
781
|
+
<A, B>(self: Iterable<A>, f: (a: A, i: number) => Option<B>): Iterable<B>
|
|
782
|
+
} = dual(
|
|
783
|
+
2,
|
|
784
|
+
<A, B>(self: Iterable<A>, f: (a: A, i: number) => Option<B>): Iterable<B> => ({
|
|
785
|
+
[Symbol.iterator]() {
|
|
786
|
+
const iterator = self[Symbol.iterator]()
|
|
787
|
+
let i = 0
|
|
788
|
+
return {
|
|
789
|
+
next() {
|
|
790
|
+
let result = iterator.next()
|
|
791
|
+
while (!result.done) {
|
|
792
|
+
const b = f(result.value, i++)
|
|
793
|
+
if (O.isSome(b)) {
|
|
794
|
+
return { done: false, value: b.value }
|
|
795
|
+
}
|
|
796
|
+
result = iterator.next()
|
|
797
|
+
}
|
|
798
|
+
return { done: true, value: undefined }
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
})
|
|
803
|
+
)
|
|
804
|
+
|
|
805
|
+
/**
|
|
806
|
+
* Transforms all elements of the `Iterable` for as long as the specified function returns some value
|
|
807
|
+
*
|
|
808
|
+
* @category filtering
|
|
809
|
+
* @since 2.0.0
|
|
810
|
+
*/
|
|
811
|
+
export const filterMapWhile: {
|
|
812
|
+
<A, B>(f: (a: A, i: number) => Option<B>): (self: Iterable<A>) => Iterable<B>
|
|
813
|
+
<A, B>(self: Iterable<A>, f: (a: A, i: number) => Option<B>): Iterable<B>
|
|
814
|
+
} = dual(2, <A, B>(self: Iterable<A>, f: (a: A, i: number) => Option<B>) => ({
|
|
815
|
+
[Symbol.iterator]() {
|
|
816
|
+
const iterator = self[Symbol.iterator]()
|
|
817
|
+
let i = 0
|
|
818
|
+
return {
|
|
819
|
+
next() {
|
|
820
|
+
const result = iterator.next()
|
|
821
|
+
if (result.done) {
|
|
822
|
+
return { done: true, value: undefined }
|
|
823
|
+
}
|
|
824
|
+
const b = f(result.value, i++)
|
|
825
|
+
if (O.isSome(b)) {
|
|
826
|
+
return { done: false, value: b.value }
|
|
827
|
+
}
|
|
828
|
+
return { done: true, value: undefined }
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
}))
|
|
833
|
+
|
|
834
|
+
/**
|
|
835
|
+
* Retrieves the `Some` values from an `Iterable` of `Option`s.
|
|
836
|
+
*
|
|
837
|
+
* @example
|
|
838
|
+
* ```ts
|
|
839
|
+
* import * as assert from "node:assert"
|
|
840
|
+
* import { Iterable, Option } from "effect"
|
|
841
|
+
*
|
|
842
|
+
* assert.deepStrictEqual(
|
|
843
|
+
* Array.from(Iterable.getSomes([Option.some(1), Option.none(), Option.some(2)])),
|
|
844
|
+
* [1, 2]
|
|
845
|
+
* )
|
|
846
|
+
* ```
|
|
847
|
+
*
|
|
848
|
+
* @category filtering
|
|
849
|
+
* @since 2.0.0
|
|
850
|
+
*/
|
|
851
|
+
export const getSomes: <A>(self: Iterable<Option<A>>) => Iterable<A> = filterMap(identity)
|
|
852
|
+
|
|
853
|
+
/**
|
|
854
|
+
* Retrieves the `Left` values from an `Iterable` of `Either`s.
|
|
855
|
+
*
|
|
856
|
+
* @example
|
|
857
|
+
* ```ts
|
|
858
|
+
* import * as assert from "node:assert"
|
|
859
|
+
* import { Iterable, Either } from "effect"
|
|
860
|
+
*
|
|
861
|
+
* assert.deepStrictEqual(
|
|
862
|
+
* Array.from(Iterable.getLefts([Either.right(1), Either.left("err"), Either.right(2)])),
|
|
863
|
+
* ["err"]
|
|
864
|
+
* )
|
|
865
|
+
* ```
|
|
866
|
+
*
|
|
867
|
+
* @category filtering
|
|
868
|
+
* @since 2.0.0
|
|
869
|
+
*/
|
|
870
|
+
export const getLefts = <R, L>(self: Iterable<Either<R, L>>): Iterable<L> => filterMap(self, E.getLeft)
|
|
871
|
+
|
|
872
|
+
/**
|
|
873
|
+
* Retrieves the `Right` values from an `Iterable` of `Either`s.
|
|
874
|
+
*
|
|
875
|
+
* @example
|
|
876
|
+
* ```ts
|
|
877
|
+
* import * as assert from "node:assert"
|
|
878
|
+
* import { Iterable, Either } from "effect"
|
|
879
|
+
*
|
|
880
|
+
* assert.deepStrictEqual(
|
|
881
|
+
* Array.from(Iterable.getRights([Either.right(1), Either.left("err"), Either.right(2)])),
|
|
882
|
+
* [1, 2]
|
|
883
|
+
* )
|
|
884
|
+
* ```
|
|
885
|
+
*
|
|
886
|
+
* @category filtering
|
|
887
|
+
* @since 2.0.0
|
|
888
|
+
*/
|
|
889
|
+
export const getRights = <R, L>(self: Iterable<Either<R, L>>): Iterable<R> => filterMap(self, E.getRight)
|
|
890
|
+
|
|
891
|
+
/**
|
|
892
|
+
* @category filtering
|
|
893
|
+
* @since 2.0.0
|
|
894
|
+
*/
|
|
895
|
+
export const filter: {
|
|
896
|
+
<A, B extends A>(refinement: (a: NoInfer<A>, i: number) => a is B): (self: Iterable<A>) => Iterable<B>
|
|
897
|
+
<A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Iterable<A>
|
|
898
|
+
<A, B extends A>(self: Iterable<A>, refinement: (a: A, i: number) => a is B): Iterable<B>
|
|
899
|
+
<A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Iterable<A>
|
|
900
|
+
} = dual(
|
|
901
|
+
2,
|
|
902
|
+
<A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Iterable<A> => ({
|
|
903
|
+
[Symbol.iterator]() {
|
|
904
|
+
const iterator = self[Symbol.iterator]()
|
|
905
|
+
let i = 0
|
|
906
|
+
return {
|
|
907
|
+
next() {
|
|
908
|
+
let result = iterator.next()
|
|
909
|
+
while (!result.done) {
|
|
910
|
+
if (predicate(result.value, i++)) {
|
|
911
|
+
return { done: false, value: result.value }
|
|
912
|
+
}
|
|
913
|
+
result = iterator.next()
|
|
914
|
+
}
|
|
915
|
+
return { done: true, value: undefined }
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
})
|
|
920
|
+
)
|
|
921
|
+
|
|
922
|
+
/**
|
|
923
|
+
* @category sequencing
|
|
924
|
+
* @since 2.0.0
|
|
925
|
+
*/
|
|
926
|
+
export const flatMapNullable: {
|
|
927
|
+
<A, B>(f: (a: A) => B | null | undefined): (self: Iterable<A>) => Iterable<NonNullable<B>>
|
|
928
|
+
<A, B>(self: Iterable<A>, f: (a: A) => B | null | undefined): Iterable<NonNullable<B>>
|
|
929
|
+
} = dual(
|
|
930
|
+
2,
|
|
931
|
+
<A, B>(self: Iterable<A>, f: (a: A) => B | null | undefined): Iterable<NonNullable<B>> =>
|
|
932
|
+
filterMap(self, (a) => {
|
|
933
|
+
const b = f(a)
|
|
934
|
+
return b == null ? O.none() : O.some(b)
|
|
935
|
+
})
|
|
936
|
+
)
|
|
937
|
+
|
|
938
|
+
/**
|
|
939
|
+
* Check if a predicate holds true for some `Iterable` element.
|
|
940
|
+
*
|
|
941
|
+
* @category elements
|
|
942
|
+
* @since 2.0.0
|
|
943
|
+
*/
|
|
944
|
+
export const some: {
|
|
945
|
+
<A>(predicate: (a: A, i: number) => boolean): (self: Iterable<A>) => boolean
|
|
946
|
+
<A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): boolean
|
|
947
|
+
} = dual(
|
|
948
|
+
2,
|
|
949
|
+
<A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): boolean => {
|
|
950
|
+
let i = 0
|
|
951
|
+
for (const a of self) {
|
|
952
|
+
if (predicate(a, i++)) {
|
|
953
|
+
return true
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
return false
|
|
957
|
+
}
|
|
958
|
+
)
|
|
959
|
+
|
|
960
|
+
/**
|
|
961
|
+
* @category constructors
|
|
962
|
+
* @since 2.0.0
|
|
963
|
+
*/
|
|
964
|
+
export const unfold = <B, A>(b: B, f: (b: B) => Option<readonly [A, B]>): Iterable<A> => ({
|
|
965
|
+
[Symbol.iterator]() {
|
|
966
|
+
let next = b
|
|
967
|
+
return {
|
|
968
|
+
next() {
|
|
969
|
+
const o = f(next)
|
|
970
|
+
if (O.isNone(o)) {
|
|
971
|
+
return { done: true, value: undefined }
|
|
972
|
+
}
|
|
973
|
+
const [a, b] = o.value
|
|
974
|
+
next = b
|
|
975
|
+
return { done: false, value: a }
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
})
|
|
980
|
+
|
|
981
|
+
/**
|
|
982
|
+
* Iterate over the `Iterable` applying `f`.
|
|
983
|
+
*
|
|
984
|
+
* @since 2.0.0
|
|
985
|
+
*/
|
|
986
|
+
export const forEach: {
|
|
987
|
+
<A>(f: (a: A, i: number) => void): (self: Iterable<A>) => void
|
|
988
|
+
<A>(self: Iterable<A>, f: (a: A, i: number) => void): void
|
|
989
|
+
} = dual(2, <A>(self: Iterable<A>, f: (a: A, i: number) => void): void => {
|
|
990
|
+
let i = 0
|
|
991
|
+
for (const a of self) {
|
|
992
|
+
f(a, i++)
|
|
993
|
+
}
|
|
994
|
+
})
|
|
995
|
+
|
|
996
|
+
/**
|
|
997
|
+
* @category folding
|
|
998
|
+
* @since 2.0.0
|
|
999
|
+
*/
|
|
1000
|
+
export const reduce: {
|
|
1001
|
+
<B, A>(b: B, f: (b: B, a: A, i: number) => B): (self: Iterable<A>) => B
|
|
1002
|
+
<A, B>(self: Iterable<A>, b: B, f: (b: B, a: A, i: number) => B): B
|
|
1003
|
+
} = dual(3, <A, B>(self: Iterable<A>, b: B, f: (b: B, a: A, i: number) => B): B => {
|
|
1004
|
+
if (Array.isArray(self)) {
|
|
1005
|
+
return self.reduce(f, b)
|
|
1006
|
+
}
|
|
1007
|
+
let i = 0
|
|
1008
|
+
let result = b
|
|
1009
|
+
for (const n of self) {
|
|
1010
|
+
result = f(result, n, i++)
|
|
1011
|
+
}
|
|
1012
|
+
return result
|
|
1013
|
+
})
|
|
1014
|
+
|
|
1015
|
+
/**
|
|
1016
|
+
* Deduplicates adjacent elements that are identical using the provided `isEquivalent` function.
|
|
1017
|
+
*
|
|
1018
|
+
* @since 2.0.0
|
|
1019
|
+
*/
|
|
1020
|
+
export const dedupeAdjacentWith: {
|
|
1021
|
+
<A>(isEquivalent: (self: A, that: A) => boolean): (self: Iterable<A>) => Iterable<A>
|
|
1022
|
+
<A>(self: Iterable<A>, isEquivalent: (self: A, that: A) => boolean): Iterable<A>
|
|
1023
|
+
} = dual(2, <A>(self: Iterable<A>, isEquivalent: (self: A, that: A) => boolean): Iterable<A> => ({
|
|
1024
|
+
[Symbol.iterator]() {
|
|
1025
|
+
const iterator = self[Symbol.iterator]()
|
|
1026
|
+
let first = true
|
|
1027
|
+
let last: A
|
|
1028
|
+
function next(): IteratorResult<A> {
|
|
1029
|
+
const result = iterator.next()
|
|
1030
|
+
if (result.done) {
|
|
1031
|
+
return { done: true, value: undefined }
|
|
1032
|
+
}
|
|
1033
|
+
if (first) {
|
|
1034
|
+
first = false
|
|
1035
|
+
last = result.value
|
|
1036
|
+
return result
|
|
1037
|
+
}
|
|
1038
|
+
const current = result.value
|
|
1039
|
+
if (isEquivalent(last, current)) {
|
|
1040
|
+
return next()
|
|
1041
|
+
}
|
|
1042
|
+
last = current
|
|
1043
|
+
return result
|
|
1044
|
+
}
|
|
1045
|
+
return { next }
|
|
1046
|
+
}
|
|
1047
|
+
}))
|
|
1048
|
+
|
|
1049
|
+
/**
|
|
1050
|
+
* Deduplicates adjacent elements that are identical.
|
|
1051
|
+
*
|
|
1052
|
+
* @since 2.0.0
|
|
1053
|
+
*/
|
|
1054
|
+
export const dedupeAdjacent: <A>(self: Iterable<A>) => Iterable<A> = dedupeAdjacentWith(Equal.equivalence())
|
|
1055
|
+
|
|
1056
|
+
/**
|
|
1057
|
+
* Zips this Iterable crosswise with the specified Iterable using the specified combiner.
|
|
1058
|
+
*
|
|
1059
|
+
* @since 2.0.0
|
|
1060
|
+
* @category elements
|
|
1061
|
+
*/
|
|
1062
|
+
export const cartesianWith: {
|
|
1063
|
+
<A, B, C>(that: Iterable<B>, f: (a: A, b: B) => C): (self: Iterable<A>) => Iterable<C>
|
|
1064
|
+
<A, B, C>(self: Iterable<A>, that: Iterable<B>, f: (a: A, b: B) => C): Iterable<C>
|
|
1065
|
+
} = dual(
|
|
1066
|
+
3,
|
|
1067
|
+
<A, B, C>(self: Iterable<A>, that: Iterable<B>, f: (a: A, b: B) => C): Iterable<C> =>
|
|
1068
|
+
flatMap(self, (a) => map(that, (b) => f(a, b)))
|
|
1069
|
+
)
|
|
1070
|
+
|
|
1071
|
+
/**
|
|
1072
|
+
* Zips this Iterable crosswise with the specified Iterable.
|
|
1073
|
+
*
|
|
1074
|
+
* @since 2.0.0
|
|
1075
|
+
* @category elements
|
|
1076
|
+
*/
|
|
1077
|
+
export const cartesian: {
|
|
1078
|
+
<B>(that: Iterable<B>): <A>(self: Iterable<A>) => Iterable<[A, B]>
|
|
1079
|
+
<A, B>(self: Iterable<A>, that: Iterable<B>): Iterable<[A, B]>
|
|
1080
|
+
} = dual(
|
|
1081
|
+
2,
|
|
1082
|
+
<A, B>(self: Iterable<A>, that: Iterable<B>): Iterable<[A, B]> => cartesianWith(self, that, (a, b) => [a, b])
|
|
1083
|
+
)
|
|
1084
|
+
|
|
1085
|
+
/**
|
|
1086
|
+
* Counts all the element of the given iterable that pass the given predicate
|
|
1087
|
+
*
|
|
1088
|
+
* **Example**
|
|
1089
|
+
*
|
|
1090
|
+
* ```ts
|
|
1091
|
+
* import { Iterable } from "effect"
|
|
1092
|
+
*
|
|
1093
|
+
* const result = Iterable.countBy([1, 2, 3, 4, 5], n => n % 2 === 0)
|
|
1094
|
+
* console.log(result) // 2
|
|
1095
|
+
* ```
|
|
1096
|
+
*
|
|
1097
|
+
* @category folding
|
|
1098
|
+
* @since 3.16.0
|
|
1099
|
+
*/
|
|
1100
|
+
export const countBy: {
|
|
1101
|
+
<A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => number
|
|
1102
|
+
<A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): number
|
|
1103
|
+
} = dual(
|
|
1104
|
+
2,
|
|
1105
|
+
<A>(
|
|
1106
|
+
self: Iterable<A>,
|
|
1107
|
+
f: (a: A, i: number) => boolean
|
|
1108
|
+
): number => {
|
|
1109
|
+
let count = 0
|
|
1110
|
+
let i = 0
|
|
1111
|
+
for (const a of self) {
|
|
1112
|
+
if (f(a, i)) {
|
|
1113
|
+
count++
|
|
1114
|
+
}
|
|
1115
|
+
i++
|
|
1116
|
+
}
|
|
1117
|
+
return count
|
|
1118
|
+
}
|
|
1119
|
+
)
|