@clayroach/effect 3.19.14-source-capture.8 → 3.19.14-source-trace.1
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/List.ts
ADDED
|
@@ -0,0 +1,977 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A data type for immutable linked lists representing ordered collections of elements of type `A`.
|
|
3
|
+
*
|
|
4
|
+
* This data type is optimal for last-in-first-out (LIFO), stack-like access patterns. If you need another access pattern, for example, random access or FIFO, consider using a collection more suited to this than `List`.
|
|
5
|
+
*
|
|
6
|
+
* **Performance**
|
|
7
|
+
*
|
|
8
|
+
* - Time: `List` has `O(1)` prepend and head/tail access. Most other operations are `O(n)` on the number of elements in the list. This includes the index-based lookup of elements, `length`, `append` and `reverse`.
|
|
9
|
+
* - Space: `List` implements structural sharing of the tail list. This means that many operations are either zero- or constant-memory cost.
|
|
10
|
+
*
|
|
11
|
+
* @since 2.0.0
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* This file is ported from
|
|
16
|
+
*
|
|
17
|
+
* Scala (https://www.scala-lang.org)
|
|
18
|
+
*
|
|
19
|
+
* Copyright EPFL and Lightbend, Inc.
|
|
20
|
+
*
|
|
21
|
+
* Licensed under Apache License 2.0
|
|
22
|
+
* (http://www.apache.org/licenses/LICENSE-2.0).
|
|
23
|
+
*/
|
|
24
|
+
import * as Arr from "./Array.js"
|
|
25
|
+
import * as Chunk from "./Chunk.js"
|
|
26
|
+
import * as Either from "./Either.js"
|
|
27
|
+
import * as Equal from "./Equal.js"
|
|
28
|
+
import * as Equivalence from "./Equivalence.js"
|
|
29
|
+
import { dual, identity, unsafeCoerce } from "./Function.js"
|
|
30
|
+
import * as Hash from "./Hash.js"
|
|
31
|
+
import { format, type Inspectable, NodeInspectSymbol, toJSON } from "./Inspectable.js"
|
|
32
|
+
import type { nonEmpty, NonEmptyIterable } from "./NonEmptyIterable.js"
|
|
33
|
+
import * as Option from "./Option.js"
|
|
34
|
+
import type { Pipeable } from "./Pipeable.js"
|
|
35
|
+
import { pipeArguments } from "./Pipeable.js"
|
|
36
|
+
import { hasProperty, type Predicate, type Refinement } from "./Predicate.js"
|
|
37
|
+
import type { NoInfer } from "./Types.js"
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Represents an immutable linked list of elements of type `A`.
|
|
41
|
+
*
|
|
42
|
+
* A `List` is optimal for last-in-first-out (LIFO), stack-like access patterns.
|
|
43
|
+
* If you need another access pattern, for example, random access or FIFO,
|
|
44
|
+
* consider using a collection more suited for that other than `List`.
|
|
45
|
+
*
|
|
46
|
+
* @since 2.0.0
|
|
47
|
+
* @category models
|
|
48
|
+
*/
|
|
49
|
+
export type List<A> = Cons<A> | Nil<A>
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @since 2.0.0
|
|
53
|
+
* @category symbol
|
|
54
|
+
*/
|
|
55
|
+
export const TypeId: unique symbol = Symbol.for("effect/List")
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @since 2.0.0
|
|
59
|
+
* @category symbol
|
|
60
|
+
*/
|
|
61
|
+
export type TypeId = typeof TypeId
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @since 2.0.0
|
|
65
|
+
* @category models
|
|
66
|
+
*/
|
|
67
|
+
export interface Nil<out A> extends Iterable<A>, Equal.Equal, Pipeable, Inspectable {
|
|
68
|
+
readonly [TypeId]: TypeId
|
|
69
|
+
readonly _tag: "Nil"
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @since 2.0.0
|
|
74
|
+
* @category models
|
|
75
|
+
*/
|
|
76
|
+
export interface Cons<out A> extends NonEmptyIterable<A>, Equal.Equal, Pipeable, Inspectable {
|
|
77
|
+
readonly [TypeId]: TypeId
|
|
78
|
+
readonly _tag: "Cons"
|
|
79
|
+
readonly head: A
|
|
80
|
+
readonly tail: List<A>
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Converts the specified `List` to an `Array`.
|
|
85
|
+
*
|
|
86
|
+
* @category conversions
|
|
87
|
+
* @since 2.0.0
|
|
88
|
+
*/
|
|
89
|
+
export const toArray = <A>(self: List<A>): Array<A> => Arr.fromIterable(self)
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @category equivalence
|
|
93
|
+
* @since 2.0.0
|
|
94
|
+
*/
|
|
95
|
+
export const getEquivalence = <A>(isEquivalent: Equivalence.Equivalence<A>): Equivalence.Equivalence<List<A>> =>
|
|
96
|
+
Equivalence.mapInput(Arr.getEquivalence(isEquivalent), toArray<A>)
|
|
97
|
+
|
|
98
|
+
const _equivalence = getEquivalence(Equal.equals)
|
|
99
|
+
|
|
100
|
+
const ConsProto: Omit<Cons<unknown>, "head" | "tail" | typeof nonEmpty> = {
|
|
101
|
+
[TypeId]: TypeId,
|
|
102
|
+
_tag: "Cons",
|
|
103
|
+
toString(this: Cons<unknown>) {
|
|
104
|
+
return format(this.toJSON())
|
|
105
|
+
},
|
|
106
|
+
toJSON(this: Cons<unknown>) {
|
|
107
|
+
return {
|
|
108
|
+
_id: "List",
|
|
109
|
+
_tag: "Cons",
|
|
110
|
+
values: toArray(this).map(toJSON)
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
[NodeInspectSymbol]() {
|
|
114
|
+
return this.toJSON()
|
|
115
|
+
},
|
|
116
|
+
[Equal.symbol](this: Cons<unknown>, that: unknown): boolean {
|
|
117
|
+
return isList(that) &&
|
|
118
|
+
this._tag === that._tag &&
|
|
119
|
+
_equivalence(this, that)
|
|
120
|
+
},
|
|
121
|
+
[Hash.symbol](this: Cons<unknown>): number {
|
|
122
|
+
return Hash.cached(this, Hash.array(toArray(this)))
|
|
123
|
+
},
|
|
124
|
+
[Symbol.iterator](this: Cons<unknown>): Iterator<unknown> {
|
|
125
|
+
let done = false
|
|
126
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
127
|
+
let self: List<unknown> = this
|
|
128
|
+
return {
|
|
129
|
+
next() {
|
|
130
|
+
if (done) {
|
|
131
|
+
return this.return!()
|
|
132
|
+
}
|
|
133
|
+
if (self._tag === "Nil") {
|
|
134
|
+
done = true
|
|
135
|
+
return this.return!()
|
|
136
|
+
}
|
|
137
|
+
const value: unknown = self.head
|
|
138
|
+
self = self.tail
|
|
139
|
+
return { done, value }
|
|
140
|
+
},
|
|
141
|
+
return(value?: unknown) {
|
|
142
|
+
if (!done) {
|
|
143
|
+
done = true
|
|
144
|
+
}
|
|
145
|
+
return { done: true, value }
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
pipe() {
|
|
150
|
+
return pipeArguments(this, arguments)
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
interface MutableCons<A> extends Cons<A> {
|
|
155
|
+
head: A
|
|
156
|
+
tail: List<A>
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const makeCons = <A>(head: A, tail: List<A>): MutableCons<A> => {
|
|
160
|
+
const cons = Object.create(ConsProto)
|
|
161
|
+
cons.head = head
|
|
162
|
+
cons.tail = tail
|
|
163
|
+
return cons
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const NilHash = Hash.string("Nil")
|
|
167
|
+
const NilProto: Nil<unknown> = {
|
|
168
|
+
[TypeId]: TypeId,
|
|
169
|
+
_tag: "Nil",
|
|
170
|
+
toString() {
|
|
171
|
+
return format(this.toJSON())
|
|
172
|
+
},
|
|
173
|
+
toJSON() {
|
|
174
|
+
return {
|
|
175
|
+
_id: "List",
|
|
176
|
+
_tag: "Nil"
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
[NodeInspectSymbol]() {
|
|
180
|
+
return this.toJSON()
|
|
181
|
+
},
|
|
182
|
+
[Hash.symbol](): number {
|
|
183
|
+
return NilHash
|
|
184
|
+
},
|
|
185
|
+
[Equal.symbol](that: unknown): boolean {
|
|
186
|
+
return isList(that) && this._tag === that._tag
|
|
187
|
+
},
|
|
188
|
+
[Symbol.iterator](): Iterator<unknown> {
|
|
189
|
+
return {
|
|
190
|
+
next() {
|
|
191
|
+
return { done: true, value: undefined }
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
pipe() {
|
|
196
|
+
return pipeArguments(this, arguments)
|
|
197
|
+
}
|
|
198
|
+
} as const
|
|
199
|
+
|
|
200
|
+
const _Nil = Object.create(NilProto) as Nil<never>
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Returns `true` if the specified value is a `List`, `false` otherwise.
|
|
204
|
+
*
|
|
205
|
+
* @since 2.0.0
|
|
206
|
+
* @category refinements
|
|
207
|
+
*/
|
|
208
|
+
export const isList: {
|
|
209
|
+
<A>(u: Iterable<A>): u is List<A>
|
|
210
|
+
(u: unknown): u is List<unknown>
|
|
211
|
+
} = (u: unknown): u is List<unknown> => hasProperty(u, TypeId)
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Returns `true` if the specified value is a `List.Nil<A>`, `false` otherwise.
|
|
215
|
+
*
|
|
216
|
+
* @since 2.0.0
|
|
217
|
+
* @category refinements
|
|
218
|
+
*/
|
|
219
|
+
export const isNil = <A>(self: List<A>): self is Nil<A> => self._tag === "Nil"
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Returns `true` if the specified value is a `List.Cons<A>`, `false` otherwise.
|
|
223
|
+
*
|
|
224
|
+
* @since 2.0.0
|
|
225
|
+
* @category refinements
|
|
226
|
+
*/
|
|
227
|
+
export const isCons = <A>(self: List<A>): self is Cons<A> => self._tag === "Cons"
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Returns the number of elements contained in the specified `List`
|
|
231
|
+
*
|
|
232
|
+
* @since 2.0.0
|
|
233
|
+
* @category getters
|
|
234
|
+
*/
|
|
235
|
+
export const size = <A>(self: List<A>): number => {
|
|
236
|
+
let these = self
|
|
237
|
+
let len = 0
|
|
238
|
+
while (!isNil(these)) {
|
|
239
|
+
len += 1
|
|
240
|
+
these = these.tail
|
|
241
|
+
}
|
|
242
|
+
return len
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Constructs a new empty `List<A>`.
|
|
247
|
+
*
|
|
248
|
+
* @since 2.0.0
|
|
249
|
+
* @category constructors
|
|
250
|
+
*/
|
|
251
|
+
export const nil = <A = never>(): List<A> => _Nil
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Constructs a new `List.Cons<A>` from the specified `head` and `tail` values.
|
|
255
|
+
*
|
|
256
|
+
* @since 2.0.0
|
|
257
|
+
* @category constructors
|
|
258
|
+
*/
|
|
259
|
+
export const cons = <A>(head: A, tail: List<A>): Cons<A> => makeCons(head, tail)
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Constructs a new empty `List<A>`.
|
|
263
|
+
*
|
|
264
|
+
* Alias of {@link nil}.
|
|
265
|
+
*
|
|
266
|
+
* @since 2.0.0
|
|
267
|
+
* @category constructors
|
|
268
|
+
*/
|
|
269
|
+
export const empty = nil
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Constructs a new `List<A>` from the specified value.
|
|
273
|
+
*
|
|
274
|
+
* @since 2.0.0
|
|
275
|
+
* @category constructors
|
|
276
|
+
*/
|
|
277
|
+
export const of = <A>(value: A): Cons<A> => makeCons(value, _Nil)
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Creates a new `List` from an iterable collection of values.
|
|
281
|
+
*
|
|
282
|
+
* @since 2.0.0
|
|
283
|
+
* @category constructors
|
|
284
|
+
*/
|
|
285
|
+
export const fromIterable = <A>(prefix: Iterable<A>): List<A> => {
|
|
286
|
+
const iterator = prefix[Symbol.iterator]()
|
|
287
|
+
let next: IteratorResult<A>
|
|
288
|
+
if ((next = iterator.next()) && !next.done) {
|
|
289
|
+
const result = makeCons(next.value, _Nil)
|
|
290
|
+
let curr = result
|
|
291
|
+
while ((next = iterator.next()) && !next.done) {
|
|
292
|
+
const temp = makeCons(next.value, _Nil)
|
|
293
|
+
curr.tail = temp
|
|
294
|
+
curr = temp
|
|
295
|
+
}
|
|
296
|
+
return result
|
|
297
|
+
} else {
|
|
298
|
+
return _Nil
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Constructs a new `List<A>` from the specified values.
|
|
304
|
+
*
|
|
305
|
+
* @since 2.0.0
|
|
306
|
+
* @category constructors
|
|
307
|
+
*/
|
|
308
|
+
export const make = <Elements extends readonly [any, ...Array<any>]>(
|
|
309
|
+
...elements: Elements
|
|
310
|
+
): Cons<Elements[number]> => fromIterable(elements) as any
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Appends the specified element to the end of the `List`, creating a new `Cons`.
|
|
314
|
+
*
|
|
315
|
+
* @category concatenating
|
|
316
|
+
* @since 2.0.0
|
|
317
|
+
*/
|
|
318
|
+
export const append: {
|
|
319
|
+
<B>(element: B): <A>(self: List<A>) => Cons<A | B>
|
|
320
|
+
<A, B>(self: List<A>, element: B): Cons<A | B>
|
|
321
|
+
} = dual(2, <A, B>(self: List<A>, element: B): Cons<A | B> => appendAll(self, of(element)))
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Concatenates two lists, combining their elements.
|
|
325
|
+
* If either list is non-empty, the result is also a non-empty list.
|
|
326
|
+
*
|
|
327
|
+
* @example
|
|
328
|
+
* ```ts
|
|
329
|
+
* import * as assert from "node:assert"
|
|
330
|
+
* import { List } from "effect"
|
|
331
|
+
*
|
|
332
|
+
* assert.deepStrictEqual(
|
|
333
|
+
* List.make(1, 2).pipe(List.appendAll(List.make("a", "b")), List.toArray),
|
|
334
|
+
* [1, 2, "a", "b"]
|
|
335
|
+
* )
|
|
336
|
+
* ```
|
|
337
|
+
*
|
|
338
|
+
* @category concatenating
|
|
339
|
+
* @since 2.0.0
|
|
340
|
+
*/
|
|
341
|
+
export const appendAll: {
|
|
342
|
+
<S extends List<any>, T extends List<any>>(that: T): (self: S) => List.OrNonEmpty<S, T, List.Infer<S> | List.Infer<T>>
|
|
343
|
+
<A, B>(self: List<A>, that: Cons<B>): Cons<A | B>
|
|
344
|
+
<A, B>(self: Cons<A>, that: List<B>): Cons<A | B>
|
|
345
|
+
<A, B>(self: List<A>, that: List<B>): List<A | B>
|
|
346
|
+
} = dual(2, <A, B>(self: List<A>, that: List<B>): List<A | B> => prependAll(that, self))
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Prepends the specified element to the beginning of the list.
|
|
350
|
+
*
|
|
351
|
+
* @category concatenating
|
|
352
|
+
* @since 2.0.0
|
|
353
|
+
*/
|
|
354
|
+
export const prepend: {
|
|
355
|
+
<B>(element: B): <A>(self: List<A>) => Cons<A | B>
|
|
356
|
+
<A, B>(self: List<A>, element: B): Cons<A | B>
|
|
357
|
+
} = dual(2, <A, B>(self: List<A>, element: B): Cons<A | B> => cons<A | B>(element, self))
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Prepends the specified prefix list to the beginning of the specified list.
|
|
361
|
+
* If either list is non-empty, the result is also a non-empty list.
|
|
362
|
+
*
|
|
363
|
+
* @example
|
|
364
|
+
* ```ts
|
|
365
|
+
* import * as assert from "node:assert"
|
|
366
|
+
* import { List } from "effect"
|
|
367
|
+
*
|
|
368
|
+
* assert.deepStrictEqual(
|
|
369
|
+
* List.make(1, 2).pipe(List.prependAll(List.make("a", "b")), List.toArray),
|
|
370
|
+
* ["a", "b", 1, 2]
|
|
371
|
+
* )
|
|
372
|
+
* ```
|
|
373
|
+
*
|
|
374
|
+
* @category concatenating
|
|
375
|
+
* @since 2.0.0
|
|
376
|
+
*/
|
|
377
|
+
export const prependAll: {
|
|
378
|
+
<S extends List<any>, T extends List<any>>(that: T): (self: S) => List.OrNonEmpty<S, T, List.Infer<S> | List.Infer<T>>
|
|
379
|
+
<A, B>(self: List<A>, that: Cons<B>): Cons<A | B>
|
|
380
|
+
<A, B>(self: Cons<A>, that: List<B>): Cons<A | B>
|
|
381
|
+
<A, B>(self: List<A>, that: List<B>): List<A | B>
|
|
382
|
+
} = dual(2, <A, B>(self: List<A>, prefix: List<B>): List<A | B> => {
|
|
383
|
+
if (isNil(self)) {
|
|
384
|
+
return prefix
|
|
385
|
+
} else if (isNil(prefix)) {
|
|
386
|
+
return self
|
|
387
|
+
} else {
|
|
388
|
+
const result = makeCons<A | B>(prefix.head, self)
|
|
389
|
+
let curr = result
|
|
390
|
+
let that = prefix.tail
|
|
391
|
+
while (!isNil(that)) {
|
|
392
|
+
const temp = makeCons<A | B>(that.head, self)
|
|
393
|
+
curr.tail = temp
|
|
394
|
+
curr = temp
|
|
395
|
+
that = that.tail
|
|
396
|
+
}
|
|
397
|
+
return result
|
|
398
|
+
}
|
|
399
|
+
})
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Prepends the specified prefix list (in reverse order) to the beginning of the
|
|
403
|
+
* specified list.
|
|
404
|
+
*
|
|
405
|
+
* @category concatenating
|
|
406
|
+
* @since 2.0.0
|
|
407
|
+
*/
|
|
408
|
+
export const prependAllReversed: {
|
|
409
|
+
<B>(prefix: List<B>): <A>(self: List<A>) => List<A | B>
|
|
410
|
+
<A, B>(self: List<A>, prefix: List<B>): List<A | B>
|
|
411
|
+
} = dual(2, <A, B>(self: List<A>, prefix: List<B>): List<A | B> => {
|
|
412
|
+
let out: List<A | B> = self
|
|
413
|
+
let pres = prefix
|
|
414
|
+
while (isCons(pres)) {
|
|
415
|
+
out = makeCons(pres.head, out)
|
|
416
|
+
pres = pres.tail
|
|
417
|
+
}
|
|
418
|
+
return out
|
|
419
|
+
})
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* Drops the first `n` elements from the specified list.
|
|
423
|
+
*
|
|
424
|
+
* @since 2.0.0
|
|
425
|
+
* @category combinators
|
|
426
|
+
*/
|
|
427
|
+
export const drop: {
|
|
428
|
+
(n: number): <A>(self: List<A>) => List<A>
|
|
429
|
+
<A>(self: List<A>, n: number): List<A>
|
|
430
|
+
} = dual(2, <A>(self: List<A>, n: number): List<A> => {
|
|
431
|
+
if (n <= 0) {
|
|
432
|
+
return self
|
|
433
|
+
}
|
|
434
|
+
if (n >= size(self)) {
|
|
435
|
+
return _Nil
|
|
436
|
+
}
|
|
437
|
+
let these = self
|
|
438
|
+
let i = 0
|
|
439
|
+
while (!isNil(these) && i < n) {
|
|
440
|
+
these = these.tail
|
|
441
|
+
i += 1
|
|
442
|
+
}
|
|
443
|
+
return these
|
|
444
|
+
})
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Check if a predicate holds true for every `List` element.
|
|
448
|
+
*
|
|
449
|
+
* @since 2.0.0
|
|
450
|
+
* @category elements
|
|
451
|
+
*/
|
|
452
|
+
export const every: {
|
|
453
|
+
<A, B extends A>(refinement: Refinement<NoInfer<A>, B>): (self: List<A>) => self is List<B>
|
|
454
|
+
<A>(predicate: Predicate<A>): (self: List<A>) => boolean
|
|
455
|
+
<A, B extends A>(self: List<A>, refinement: Refinement<A, B>): self is List<B>
|
|
456
|
+
<A>(self: List<A>, predicate: Predicate<A>): boolean
|
|
457
|
+
} = dual(2, <A, B extends A>(self: List<A>, refinement: Refinement<A, B>): self is List<B> => {
|
|
458
|
+
for (const a of self) {
|
|
459
|
+
if (!refinement(a)) {
|
|
460
|
+
return false
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
return true
|
|
464
|
+
})
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Check if a predicate holds true for some `List` element.
|
|
468
|
+
*
|
|
469
|
+
* @since 2.0.0
|
|
470
|
+
* @category elements
|
|
471
|
+
*/
|
|
472
|
+
export const some: {
|
|
473
|
+
<A>(predicate: Predicate<NoInfer<A>>): (self: List<A>) => self is Cons<A>
|
|
474
|
+
<A>(self: List<A>, predicate: Predicate<A>): self is Cons<A>
|
|
475
|
+
} = dual(2, <A>(self: List<A>, predicate: Predicate<A>): self is Cons<A> => {
|
|
476
|
+
let these = self
|
|
477
|
+
while (!isNil(these)) {
|
|
478
|
+
if (predicate(these.head)) {
|
|
479
|
+
return true
|
|
480
|
+
}
|
|
481
|
+
these = these.tail
|
|
482
|
+
}
|
|
483
|
+
return false
|
|
484
|
+
})
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Filters a list using the specified predicate.
|
|
488
|
+
*
|
|
489
|
+
* @since 2.0.0
|
|
490
|
+
* @category combinators
|
|
491
|
+
*/
|
|
492
|
+
export const filter: {
|
|
493
|
+
<A, B extends A>(refinement: Refinement<NoInfer<A>, B>): (self: List<A>) => List<B>
|
|
494
|
+
<A>(predicate: Predicate<NoInfer<A>>): (self: List<A>) => List<A>
|
|
495
|
+
<A, B extends A>(self: List<A>, refinement: Refinement<A, B>): List<B>
|
|
496
|
+
<A>(self: List<A>, predicate: Predicate<A>): List<A>
|
|
497
|
+
} = dual(2, <A>(self: List<A>, predicate: Predicate<A>): List<A> => noneIn(self, predicate, false))
|
|
498
|
+
|
|
499
|
+
// everything seen so far is not included
|
|
500
|
+
const noneIn = <A>(
|
|
501
|
+
self: List<A>,
|
|
502
|
+
predicate: Predicate<A>,
|
|
503
|
+
isFlipped: boolean
|
|
504
|
+
): List<A> => {
|
|
505
|
+
while (true) {
|
|
506
|
+
if (isNil(self)) {
|
|
507
|
+
return _Nil
|
|
508
|
+
} else {
|
|
509
|
+
if (predicate(self.head) !== isFlipped) {
|
|
510
|
+
return allIn(self, self.tail, predicate, isFlipped)
|
|
511
|
+
} else {
|
|
512
|
+
self = self.tail
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
// everything from 'start' is included, if everything from this point is in we can return the origin
|
|
519
|
+
// start otherwise if we discover an element that is out we must create a new partial list.
|
|
520
|
+
const allIn = <A>(
|
|
521
|
+
start: List<A>,
|
|
522
|
+
remaining: List<A>,
|
|
523
|
+
predicate: Predicate<A>,
|
|
524
|
+
isFlipped: boolean
|
|
525
|
+
): List<A> => {
|
|
526
|
+
while (true) {
|
|
527
|
+
if (isNil(remaining)) {
|
|
528
|
+
return start
|
|
529
|
+
} else {
|
|
530
|
+
if (predicate(remaining.head) !== isFlipped) {
|
|
531
|
+
remaining = remaining.tail
|
|
532
|
+
} else {
|
|
533
|
+
return partialFill(start, remaining, predicate, isFlipped)
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
// we have seen elements that should be included then one that should be excluded, start building
|
|
540
|
+
const partialFill = <A>(
|
|
541
|
+
origStart: List<A>,
|
|
542
|
+
firstMiss: List<A>,
|
|
543
|
+
predicate: Predicate<A>,
|
|
544
|
+
isFlipped: boolean
|
|
545
|
+
): List<A> => {
|
|
546
|
+
const newHead = makeCons<A>(unsafeHead(origStart)!, _Nil)
|
|
547
|
+
let toProcess = unsafeTail(origStart)! as Cons<A>
|
|
548
|
+
let currentLast = newHead
|
|
549
|
+
|
|
550
|
+
// we know that all elements are :: until at least firstMiss.tail
|
|
551
|
+
while (!(toProcess === firstMiss)) {
|
|
552
|
+
const newElem = makeCons(unsafeHead(toProcess)!, _Nil)
|
|
553
|
+
currentLast.tail = newElem
|
|
554
|
+
currentLast = unsafeCoerce(newElem)
|
|
555
|
+
toProcess = unsafeCoerce(toProcess.tail)
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
// at this point newHead points to a list which is a duplicate of all the 'in' elements up to the first miss.
|
|
559
|
+
// currentLast is the last element in that list.
|
|
560
|
+
|
|
561
|
+
// now we are going to try and share as much of the tail as we can, only moving elements across when we have to.
|
|
562
|
+
let next = firstMiss.tail
|
|
563
|
+
let nextToCopy: Cons<A> = unsafeCoerce(next) // the next element we would need to copy to our list if we cant share.
|
|
564
|
+
while (!isNil(next)) {
|
|
565
|
+
// generally recommended is next.isNonEmpty but this incurs an extra method call.
|
|
566
|
+
const head = unsafeHead(next)!
|
|
567
|
+
if (predicate(head) !== isFlipped) {
|
|
568
|
+
next = next.tail
|
|
569
|
+
} else {
|
|
570
|
+
// its not a match - do we have outstanding elements?
|
|
571
|
+
while (!(nextToCopy === next)) {
|
|
572
|
+
const newElem = makeCons(unsafeHead(nextToCopy)!, _Nil)
|
|
573
|
+
currentLast.tail = newElem
|
|
574
|
+
currentLast = newElem
|
|
575
|
+
nextToCopy = unsafeCoerce(nextToCopy.tail)
|
|
576
|
+
}
|
|
577
|
+
nextToCopy = unsafeCoerce(next.tail)
|
|
578
|
+
next = next.tail
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
// we have remaining elements - they are unchanged attach them to the end
|
|
583
|
+
if (!isNil(nextToCopy)) {
|
|
584
|
+
currentLast.tail = nextToCopy
|
|
585
|
+
}
|
|
586
|
+
return newHead
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/**
|
|
590
|
+
* Filters and maps a list using the specified partial function. The resulting
|
|
591
|
+
* list may be smaller than the input list due to the possibility of the partial
|
|
592
|
+
* function not being defined for some elements.
|
|
593
|
+
*
|
|
594
|
+
* @since 2.0.0
|
|
595
|
+
* @category combinators
|
|
596
|
+
*/
|
|
597
|
+
export const filterMap: {
|
|
598
|
+
<A, B>(f: (a: A) => Option.Option<B>): (self: List<A>) => List<B>
|
|
599
|
+
<A, B>(self: List<A>, f: (a: A) => Option.Option<B>): List<B>
|
|
600
|
+
} = dual(2, <A, B>(self: List<A>, f: (a: A) => Option.Option<B>): List<B> => {
|
|
601
|
+
const bs: Array<B> = []
|
|
602
|
+
for (const a of self) {
|
|
603
|
+
const oa = f(a)
|
|
604
|
+
if (Option.isSome(oa)) {
|
|
605
|
+
bs.push(oa.value)
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
return fromIterable(bs)
|
|
609
|
+
})
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* Removes all `None` values from the specified list.
|
|
613
|
+
*
|
|
614
|
+
* @since 2.0.0
|
|
615
|
+
* @category combinators
|
|
616
|
+
*/
|
|
617
|
+
export const compact = <A>(self: List<Option.Option<A>>): List<A> => filterMap(self, identity)
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
* Returns the first element that satisfies the specified
|
|
621
|
+
* predicate, or `None` if no such element exists.
|
|
622
|
+
*
|
|
623
|
+
* @category elements
|
|
624
|
+
* @since 2.0.0
|
|
625
|
+
*/
|
|
626
|
+
export const findFirst: {
|
|
627
|
+
<A, B extends A>(refinement: Refinement<NoInfer<A>, B>): (self: List<A>) => Option.Option<B>
|
|
628
|
+
<A>(predicate: Predicate<NoInfer<A>>): (self: List<A>) => Option.Option<A>
|
|
629
|
+
<A, B extends A>(self: List<A>, refinement: Refinement<A, B>): Option.Option<B>
|
|
630
|
+
<A>(self: List<A>, predicate: Predicate<A>): Option.Option<A>
|
|
631
|
+
} = dual(2, <A>(self: List<A>, predicate: Predicate<A>): Option.Option<A> => {
|
|
632
|
+
let these = self
|
|
633
|
+
while (!isNil(these)) {
|
|
634
|
+
if (predicate(these.head)) {
|
|
635
|
+
return Option.some(these.head)
|
|
636
|
+
}
|
|
637
|
+
these = these.tail
|
|
638
|
+
}
|
|
639
|
+
return Option.none()
|
|
640
|
+
})
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* Applies a function to each element in a list and returns a new list containing the concatenated mapped elements.
|
|
644
|
+
*
|
|
645
|
+
* @since 2.0.0
|
|
646
|
+
* @category sequencing
|
|
647
|
+
*/
|
|
648
|
+
export const flatMap: {
|
|
649
|
+
<S extends List<any>, T extends List<any>>(
|
|
650
|
+
f: (a: List.Infer<S>, i: number) => T
|
|
651
|
+
): (self: S) => List.AndNonEmpty<S, T, List.Infer<T>>
|
|
652
|
+
<A, B>(self: Cons<A>, f: (a: A, i: number) => Cons<B>): Cons<B>
|
|
653
|
+
<A, B>(self: List<A>, f: (a: A, i: number) => List<B>): List<B>
|
|
654
|
+
} = dual(2, <A, B>(self: List<A>, f: (a: A) => List<B>): List<B> => {
|
|
655
|
+
let rest = self
|
|
656
|
+
let head: MutableCons<B> | undefined = undefined
|
|
657
|
+
let tail: MutableCons<B> | undefined = undefined
|
|
658
|
+
while (!isNil(rest)) {
|
|
659
|
+
let bs = f(rest.head)
|
|
660
|
+
while (!isNil(bs)) {
|
|
661
|
+
const next = makeCons(bs.head, _Nil)
|
|
662
|
+
if (tail === undefined) {
|
|
663
|
+
head = next
|
|
664
|
+
} else {
|
|
665
|
+
tail.tail = next
|
|
666
|
+
}
|
|
667
|
+
tail = next
|
|
668
|
+
bs = bs.tail
|
|
669
|
+
}
|
|
670
|
+
rest = rest.tail
|
|
671
|
+
}
|
|
672
|
+
if (head === undefined) {
|
|
673
|
+
return _Nil
|
|
674
|
+
}
|
|
675
|
+
return head
|
|
676
|
+
})
|
|
677
|
+
|
|
678
|
+
/**
|
|
679
|
+
* Applies the specified function to each element of the `List`.
|
|
680
|
+
*
|
|
681
|
+
* @since 2.0.0
|
|
682
|
+
* @category combinators
|
|
683
|
+
*/
|
|
684
|
+
export const forEach: {
|
|
685
|
+
<A, B>(f: (a: A) => B): (self: List<A>) => void
|
|
686
|
+
<A, B>(self: List<A>, f: (a: A) => B): void
|
|
687
|
+
} = dual(2, <A, B>(self: List<A>, f: (a: A) => B): void => {
|
|
688
|
+
let these = self
|
|
689
|
+
while (!isNil(these)) {
|
|
690
|
+
f(these.head)
|
|
691
|
+
these = these.tail
|
|
692
|
+
}
|
|
693
|
+
})
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* Returns the first element of the specified list, or `None` if the list is
|
|
697
|
+
* empty.
|
|
698
|
+
*
|
|
699
|
+
* @since 2.0.0
|
|
700
|
+
* @category getters
|
|
701
|
+
*/
|
|
702
|
+
export const head = <A>(self: List<A>): Option.Option<A> => isNil(self) ? Option.none() : Option.some(self.head)
|
|
703
|
+
|
|
704
|
+
/**
|
|
705
|
+
* Returns the last element of the specified list, or `None` if the list is
|
|
706
|
+
* empty.
|
|
707
|
+
*
|
|
708
|
+
* @since 2.0.0
|
|
709
|
+
* @category getters
|
|
710
|
+
*/
|
|
711
|
+
export const last = <A>(self: List<A>): Option.Option<A> => isNil(self) ? Option.none() : Option.some(unsafeLast(self)!)
|
|
712
|
+
|
|
713
|
+
/**
|
|
714
|
+
* @since 2.0.0
|
|
715
|
+
*/
|
|
716
|
+
export declare namespace List {
|
|
717
|
+
/**
|
|
718
|
+
* @since 2.0.0
|
|
719
|
+
*/
|
|
720
|
+
export type Infer<S extends List<any>> = S extends List<infer A> ? A : never
|
|
721
|
+
|
|
722
|
+
/**
|
|
723
|
+
* @since 2.0.0
|
|
724
|
+
*/
|
|
725
|
+
export type With<S extends List<any>, A> = S extends Cons<any> ? Cons<A> : List<A>
|
|
726
|
+
|
|
727
|
+
/**
|
|
728
|
+
* @since 2.0.0
|
|
729
|
+
*/
|
|
730
|
+
export type OrNonEmpty<S extends List<any>, T extends List<any>, A> = S extends Cons<any> ? Cons<A>
|
|
731
|
+
: T extends Cons<any> ? Cons<A>
|
|
732
|
+
: List<A>
|
|
733
|
+
|
|
734
|
+
/**
|
|
735
|
+
* @since 2.0.0
|
|
736
|
+
*/
|
|
737
|
+
export type AndNonEmpty<S extends List<any>, T extends List<any>, A> = S extends Cons<any> ?
|
|
738
|
+
T extends Cons<any> ? Cons<A>
|
|
739
|
+
: List<A> :
|
|
740
|
+
List<A>
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
/**
|
|
744
|
+
* Applies the specified mapping function to each element of the list.
|
|
745
|
+
*
|
|
746
|
+
* @since 2.0.0
|
|
747
|
+
* @category mapping
|
|
748
|
+
*/
|
|
749
|
+
export const map: {
|
|
750
|
+
<S extends List<any>, B>(f: (a: List.Infer<S>, i: number) => B): (self: S) => List.With<S, B>
|
|
751
|
+
<S extends List<any>, B>(self: S, f: (a: List.Infer<S>, i: number) => B): List.With<S, B>
|
|
752
|
+
} = dual(2, <A, B>(self: List<A>, f: (a: A, i: number) => B): List<B> => {
|
|
753
|
+
if (isNil(self)) {
|
|
754
|
+
return self as unknown as List<B>
|
|
755
|
+
} else {
|
|
756
|
+
let i = 0
|
|
757
|
+
const head = makeCons(f(self.head, i++), _Nil)
|
|
758
|
+
let nextHead = head
|
|
759
|
+
let rest = self.tail
|
|
760
|
+
while (!isNil(rest)) {
|
|
761
|
+
const next = makeCons(f(rest.head, i++), _Nil)
|
|
762
|
+
nextHead.tail = next
|
|
763
|
+
nextHead = next
|
|
764
|
+
rest = rest.tail
|
|
765
|
+
}
|
|
766
|
+
return head
|
|
767
|
+
}
|
|
768
|
+
})
|
|
769
|
+
|
|
770
|
+
/**
|
|
771
|
+
* Partition a list into two lists, where the first list contains all elements
|
|
772
|
+
* that did not satisfy the specified predicate, and the second list contains
|
|
773
|
+
* all elements that did satisfy the specified predicate.
|
|
774
|
+
*
|
|
775
|
+
* @since 2.0.0
|
|
776
|
+
* @category combinators
|
|
777
|
+
*/
|
|
778
|
+
export const partition: {
|
|
779
|
+
<A, B extends A>(
|
|
780
|
+
refinement: Refinement<NoInfer<A>, B>
|
|
781
|
+
): (self: List<A>) => [excluded: List<Exclude<A, B>>, satisfying: List<B>]
|
|
782
|
+
<A>(predicate: Predicate<NoInfer<A>>): (self: List<A>) => [excluded: List<A>, satisfying: List<A>]
|
|
783
|
+
<A, B extends A>(self: List<A>, refinement: Refinement<A, B>): [excluded: List<Exclude<A, B>>, satisfying: List<B>]
|
|
784
|
+
<A>(self: List<A>, predicate: Predicate<A>): [excluded: List<A>, satisfying: List<A>]
|
|
785
|
+
} = dual(2, <A>(self: List<A>, predicate: Predicate<A>): [excluded: List<A>, satisfying: List<A>] => {
|
|
786
|
+
const left: Array<A> = []
|
|
787
|
+
const right: Array<A> = []
|
|
788
|
+
for (const a of self) {
|
|
789
|
+
if (predicate(a)) {
|
|
790
|
+
right.push(a)
|
|
791
|
+
} else {
|
|
792
|
+
left.push(a)
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
return [fromIterable(left), fromIterable(right)]
|
|
796
|
+
})
|
|
797
|
+
|
|
798
|
+
/**
|
|
799
|
+
* Partition a list into two lists, where the first list contains all elements
|
|
800
|
+
* for which the specified function returned a `Left`, and the second list
|
|
801
|
+
* contains all elements for which the specified function returned a `Right`.
|
|
802
|
+
*
|
|
803
|
+
* @since 2.0.0
|
|
804
|
+
* @category combinators
|
|
805
|
+
*/
|
|
806
|
+
export const partitionMap: {
|
|
807
|
+
<A, B, C>(f: (a: A) => Either.Either<C, B>): (self: List<A>) => [left: List<B>, right: List<C>]
|
|
808
|
+
<A, B, C>(self: List<A>, f: (a: A) => Either.Either<C, B>): [left: List<B>, right: List<C>]
|
|
809
|
+
} = dual(2, <A, B, C>(self: List<A>, f: (a: A) => Either.Either<C, B>): [left: List<B>, right: List<C>] => {
|
|
810
|
+
const left: Array<B> = []
|
|
811
|
+
const right: Array<C> = []
|
|
812
|
+
for (const a of self) {
|
|
813
|
+
const e = f(a)
|
|
814
|
+
if (Either.isLeft(e)) {
|
|
815
|
+
left.push(e.left)
|
|
816
|
+
} else {
|
|
817
|
+
right.push(e.right)
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
return [fromIterable(left), fromIterable(right)]
|
|
821
|
+
})
|
|
822
|
+
|
|
823
|
+
/**
|
|
824
|
+
* Folds over the elements of the list using the specified function, using the
|
|
825
|
+
* specified initial value.
|
|
826
|
+
*
|
|
827
|
+
* @since 2.0.0
|
|
828
|
+
* @category folding
|
|
829
|
+
*/
|
|
830
|
+
export const reduce: {
|
|
831
|
+
<Z, A>(zero: Z, f: (b: Z, a: A) => Z): (self: List<A>) => Z
|
|
832
|
+
<A, Z>(self: List<A>, zero: Z, f: (b: Z, a: A) => Z): Z
|
|
833
|
+
} = dual(3, <A, Z>(self: List<A>, zero: Z, f: (b: Z, a: A) => Z): Z => {
|
|
834
|
+
let acc = zero
|
|
835
|
+
let these = self
|
|
836
|
+
while (!isNil(these)) {
|
|
837
|
+
acc = f(acc, these.head)
|
|
838
|
+
these = these.tail
|
|
839
|
+
}
|
|
840
|
+
return acc
|
|
841
|
+
})
|
|
842
|
+
|
|
843
|
+
/**
|
|
844
|
+
* Folds over the elements of the list using the specified function, beginning
|
|
845
|
+
* with the last element of the list, using the specified initial value.
|
|
846
|
+
*
|
|
847
|
+
* @since 2.0.0
|
|
848
|
+
* @category folding
|
|
849
|
+
*/
|
|
850
|
+
export const reduceRight: {
|
|
851
|
+
<Z, A>(zero: Z, f: (accumulator: Z, value: A) => Z): (self: List<A>) => Z
|
|
852
|
+
<Z, A>(self: List<A>, zero: Z, f: (accumulator: Z, value: A) => Z): Z
|
|
853
|
+
} = dual(3, <Z, A>(self: List<A>, zero: Z, f: (accumulator: Z, value: A) => Z): Z => {
|
|
854
|
+
let acc = zero
|
|
855
|
+
let these = reverse(self)
|
|
856
|
+
while (!isNil(these)) {
|
|
857
|
+
acc = f(acc, these.head)
|
|
858
|
+
these = these.tail
|
|
859
|
+
}
|
|
860
|
+
return acc
|
|
861
|
+
})
|
|
862
|
+
|
|
863
|
+
/**
|
|
864
|
+
* Returns a new list with the elements of the specified list in reverse order.
|
|
865
|
+
*
|
|
866
|
+
* @since 2.0.0
|
|
867
|
+
* @category elements
|
|
868
|
+
*/
|
|
869
|
+
export const reverse = <A>(self: List<A>): List<A> => {
|
|
870
|
+
let result = empty<A>()
|
|
871
|
+
let these = self
|
|
872
|
+
while (!isNil(these)) {
|
|
873
|
+
result = prepend(result, these.head)
|
|
874
|
+
these = these.tail
|
|
875
|
+
}
|
|
876
|
+
return result
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
/**
|
|
880
|
+
* Splits the specified list into two lists at the specified index.
|
|
881
|
+
*
|
|
882
|
+
* @since 2.0.0
|
|
883
|
+
* @category combinators
|
|
884
|
+
*/
|
|
885
|
+
export const splitAt: {
|
|
886
|
+
(n: number): <A>(self: List<A>) => [beforeIndex: List<A>, fromIndex: List<A>]
|
|
887
|
+
<A>(self: List<A>, n: number): [beforeIndex: List<A>, fromIndex: List<A>]
|
|
888
|
+
} = dual(2, <A>(self: List<A>, n: number): [List<A>, List<A>] => [take(self, n), drop(self, n)])
|
|
889
|
+
|
|
890
|
+
/**
|
|
891
|
+
* Returns the tail of the specified list, or `None` if the list is empty.
|
|
892
|
+
*
|
|
893
|
+
* @since 2.0.0
|
|
894
|
+
* @category getters
|
|
895
|
+
*/
|
|
896
|
+
export const tail = <A>(self: List<A>): Option.Option<List<A>> => isNil(self) ? Option.none() : Option.some(self.tail)
|
|
897
|
+
|
|
898
|
+
/**
|
|
899
|
+
* Takes the specified number of elements from the beginning of the specified
|
|
900
|
+
* list.
|
|
901
|
+
*
|
|
902
|
+
* @since 2.0.0
|
|
903
|
+
* @category combinators
|
|
904
|
+
*/
|
|
905
|
+
export const take: {
|
|
906
|
+
(n: number): <A>(self: List<A>) => List<A>
|
|
907
|
+
<A>(self: List<A>, n: number): List<A>
|
|
908
|
+
} = dual(2, <A>(self: List<A>, n: number): List<A> => {
|
|
909
|
+
if (n <= 0) {
|
|
910
|
+
return _Nil
|
|
911
|
+
}
|
|
912
|
+
if (n >= size(self)) {
|
|
913
|
+
return self
|
|
914
|
+
}
|
|
915
|
+
let these = make(unsafeHead(self))
|
|
916
|
+
let current = unsafeTail(self)!
|
|
917
|
+
for (let i = 1; i < n; i++) {
|
|
918
|
+
these = makeCons(unsafeHead(current), these)
|
|
919
|
+
current = unsafeTail(current!)
|
|
920
|
+
}
|
|
921
|
+
return reverse(these)
|
|
922
|
+
})
|
|
923
|
+
|
|
924
|
+
/**
|
|
925
|
+
* Converts the specified `List` to a `Chunk`.
|
|
926
|
+
*
|
|
927
|
+
* @since 2.0.0
|
|
928
|
+
* @category conversions
|
|
929
|
+
*/
|
|
930
|
+
export const toChunk = <A>(self: List<A>): Chunk.Chunk<A> => Chunk.fromIterable(self)
|
|
931
|
+
|
|
932
|
+
const getExpectedListToBeNonEmptyErrorMessage = "Expected List to be non-empty"
|
|
933
|
+
|
|
934
|
+
/**
|
|
935
|
+
* Unsafely returns the first element of the specified `List`.
|
|
936
|
+
*
|
|
937
|
+
* @since 2.0.0
|
|
938
|
+
* @category unsafe
|
|
939
|
+
*/
|
|
940
|
+
export const unsafeHead = <A>(self: List<A>): A => {
|
|
941
|
+
if (isNil(self)) {
|
|
942
|
+
throw new Error(getExpectedListToBeNonEmptyErrorMessage)
|
|
943
|
+
}
|
|
944
|
+
return self.head
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
/**
|
|
948
|
+
* Unsafely returns the last element of the specified `List`.
|
|
949
|
+
*
|
|
950
|
+
* @since 2.0.0
|
|
951
|
+
* @category unsafe
|
|
952
|
+
*/
|
|
953
|
+
export const unsafeLast = <A>(self: List<A>): A => {
|
|
954
|
+
if (isNil(self)) {
|
|
955
|
+
throw new Error(getExpectedListToBeNonEmptyErrorMessage)
|
|
956
|
+
}
|
|
957
|
+
let these = self
|
|
958
|
+
let scout = self.tail
|
|
959
|
+
while (!isNil(scout)) {
|
|
960
|
+
these = scout
|
|
961
|
+
scout = scout.tail
|
|
962
|
+
}
|
|
963
|
+
return these.head
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
/**
|
|
967
|
+
* Unsafely returns the tail of the specified `List`.
|
|
968
|
+
*
|
|
969
|
+
* @since 2.0.0
|
|
970
|
+
* @category unsafe
|
|
971
|
+
*/
|
|
972
|
+
export const unsafeTail = <A>(self: List<A>): List<A> => {
|
|
973
|
+
if (isNil(self)) {
|
|
974
|
+
throw new Error(getExpectedListToBeNonEmptyErrorMessage)
|
|
975
|
+
}
|
|
976
|
+
return self.tail
|
|
977
|
+
}
|