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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (452) hide show
  1. package/SourceLocation/package.json +6 -0
  2. package/dist/cjs/Effect.js +2 -28
  3. package/dist/cjs/Effect.js.map +1 -1
  4. package/dist/cjs/FiberRef.js +12 -1
  5. package/dist/cjs/FiberRef.js.map +1 -1
  6. package/dist/cjs/Layer.js +2 -24
  7. package/dist/cjs/Layer.js.map +1 -1
  8. package/dist/cjs/RuntimeFlags.js +1 -29
  9. package/dist/cjs/RuntimeFlags.js.map +1 -1
  10. package/dist/cjs/SourceLocation.js +60 -0
  11. package/dist/cjs/SourceLocation.js.map +1 -0
  12. package/dist/cjs/Tracer.js +1 -15
  13. package/dist/cjs/Tracer.js.map +1 -1
  14. package/dist/cjs/Utils.js +1 -1
  15. package/dist/cjs/Utils.js.map +1 -1
  16. package/dist/cjs/index.js +3 -1
  17. package/dist/cjs/index.js.map +1 -1
  18. package/dist/cjs/internal/clock.js +1 -1
  19. package/dist/cjs/internal/clock.js.map +1 -1
  20. package/dist/cjs/internal/core.js +17 -50
  21. package/dist/cjs/internal/core.js.map +1 -1
  22. package/dist/cjs/internal/effect/circular.js +18 -30
  23. package/dist/cjs/internal/effect/circular.js.map +1 -1
  24. package/dist/cjs/internal/fiberRuntime.js +16 -65
  25. package/dist/cjs/internal/fiberRuntime.js.map +1 -1
  26. package/dist/cjs/internal/layer/circular.js +1 -5
  27. package/dist/cjs/internal/layer/circular.js.map +1 -1
  28. package/dist/cjs/internal/layer.js +1 -3
  29. package/dist/cjs/internal/layer.js.map +1 -1
  30. package/dist/cjs/internal/logger.js +25 -2
  31. package/dist/cjs/internal/logger.js.map +1 -1
  32. package/dist/cjs/internal/runtimeFlags.js +2 -11
  33. package/dist/cjs/internal/runtimeFlags.js.map +1 -1
  34. package/dist/cjs/internal/tracer.js +1 -114
  35. package/dist/cjs/internal/tracer.js.map +1 -1
  36. package/dist/dts/Config.d.ts +2 -2
  37. package/dist/dts/Config.d.ts.map +1 -1
  38. package/dist/dts/Effect.d.ts +8 -29
  39. package/dist/dts/Effect.d.ts.map +1 -1
  40. package/dist/dts/FiberRef.d.ts +12 -0
  41. package/dist/dts/FiberRef.d.ts.map +1 -1
  42. package/dist/dts/Layer.d.ts +0 -22
  43. package/dist/dts/Layer.d.ts.map +1 -1
  44. package/dist/dts/RuntimeFlags.d.ts +0 -28
  45. package/dist/dts/RuntimeFlags.d.ts.map +1 -1
  46. package/dist/dts/SourceLocation.d.ts +88 -0
  47. package/dist/dts/SourceLocation.d.ts.map +1 -0
  48. package/dist/dts/Tracer.d.ts +0 -15
  49. package/dist/dts/Tracer.d.ts.map +1 -1
  50. package/dist/dts/index.d.ts +6 -0
  51. package/dist/dts/index.d.ts.map +1 -1
  52. package/dist/dts/internal/core.d.ts.map +1 -1
  53. package/dist/dts/internal/layer.d.ts.map +1 -1
  54. package/dist/dts/internal/runtimeFlags.d.ts.map +1 -1
  55. package/dist/esm/Effect.js +0 -26
  56. package/dist/esm/Effect.js.map +1 -1
  57. package/dist/esm/FiberRef.js +11 -0
  58. package/dist/esm/FiberRef.js.map +1 -1
  59. package/dist/esm/Layer.js +0 -22
  60. package/dist/esm/Layer.js.map +1 -1
  61. package/dist/esm/RuntimeFlags.js +0 -28
  62. package/dist/esm/RuntimeFlags.js.map +1 -1
  63. package/dist/esm/SourceLocation.js +51 -0
  64. package/dist/esm/SourceLocation.js.map +1 -0
  65. package/dist/esm/Tracer.js +0 -14
  66. package/dist/esm/Tracer.js.map +1 -1
  67. package/dist/esm/Utils.js +1 -1
  68. package/dist/esm/Utils.js.map +1 -1
  69. package/dist/esm/index.js +6 -0
  70. package/dist/esm/index.js.map +1 -1
  71. package/dist/esm/internal/clock.js +1 -1
  72. package/dist/esm/internal/clock.js.map +1 -1
  73. package/dist/esm/internal/core.js +12 -45
  74. package/dist/esm/internal/core.js.map +1 -1
  75. package/dist/esm/internal/effect/circular.js +18 -30
  76. package/dist/esm/internal/effect/circular.js.map +1 -1
  77. package/dist/esm/internal/fiberRuntime.js +13 -60
  78. package/dist/esm/internal/fiberRuntime.js.map +1 -1
  79. package/dist/esm/internal/layer/circular.js +0 -4
  80. package/dist/esm/internal/layer/circular.js.map +1 -1
  81. package/dist/esm/internal/layer.js +0 -2
  82. package/dist/esm/internal/layer.js.map +1 -1
  83. package/dist/esm/internal/logger.js +25 -2
  84. package/dist/esm/internal/logger.js.map +1 -1
  85. package/dist/esm/internal/runtimeFlags.js +1 -9
  86. package/dist/esm/internal/runtimeFlags.js.map +1 -1
  87. package/dist/esm/internal/tracer.js +0 -111
  88. package/dist/esm/internal/tracer.js.map +1 -1
  89. package/package.json +12 -1
  90. package/src/Arbitrary.ts +1101 -0
  91. package/src/Array.ts +3589 -0
  92. package/src/BigDecimal.ts +1349 -0
  93. package/src/BigInt.ts +643 -0
  94. package/src/Boolean.ts +287 -0
  95. package/src/Brand.ts +360 -0
  96. package/src/Cache.ts +281 -0
  97. package/src/Cause.ts +1555 -0
  98. package/src/Channel.ts +2355 -0
  99. package/src/ChildExecutorDecision.ts +146 -0
  100. package/src/Chunk.ts +1495 -0
  101. package/src/Clock.ts +111 -0
  102. package/src/Config.ts +542 -0
  103. package/src/ConfigError.ts +270 -0
  104. package/src/ConfigProvider.ts +333 -0
  105. package/src/ConfigProviderPathPatch.ts +100 -0
  106. package/src/Console.ts +226 -0
  107. package/src/Context.ts +585 -0
  108. package/src/Cron.ts +706 -0
  109. package/src/Data.ts +596 -0
  110. package/src/DateTime.ts +1686 -0
  111. package/src/DefaultServices.ts +34 -0
  112. package/src/Deferred.ts +301 -0
  113. package/src/Differ.ts +450 -0
  114. package/src/Duration.ts +1000 -0
  115. package/src/Effect.ts +14817 -0
  116. package/src/Effectable.ts +107 -0
  117. package/src/Either.ts +1040 -0
  118. package/src/Encoding.ts +195 -0
  119. package/src/Equal.ts +98 -0
  120. package/src/Equivalence.ts +235 -0
  121. package/src/ExecutionPlan.ts +308 -0
  122. package/src/ExecutionStrategy.ts +119 -0
  123. package/src/Exit.ts +467 -0
  124. package/src/FastCheck.ts +9 -0
  125. package/src/Fiber.ts +744 -0
  126. package/src/FiberHandle.ts +540 -0
  127. package/src/FiberId.ts +195 -0
  128. package/src/FiberMap.ts +656 -0
  129. package/src/FiberRef.ts +444 -0
  130. package/src/FiberRefs.ts +204 -0
  131. package/src/FiberRefsPatch.ts +105 -0
  132. package/src/FiberSet.ts +491 -0
  133. package/src/FiberStatus.ts +108 -0
  134. package/src/Function.ts +1222 -0
  135. package/src/GlobalValue.ts +53 -0
  136. package/src/Graph.ts +3732 -0
  137. package/src/GroupBy.ts +103 -0
  138. package/src/HKT.ts +45 -0
  139. package/src/Hash.ts +195 -0
  140. package/src/HashMap.ts +519 -0
  141. package/src/HashRing.ts +317 -0
  142. package/src/HashSet.ts +2346 -0
  143. package/src/Inspectable.ts +287 -0
  144. package/src/Iterable.ts +1119 -0
  145. package/src/JSONSchema.ts +1044 -0
  146. package/src/KeyedPool.ts +167 -0
  147. package/src/Layer.ts +1228 -0
  148. package/src/LayerMap.ts +436 -0
  149. package/src/List.ts +977 -0
  150. package/src/LogLevel.ts +285 -0
  151. package/src/LogSpan.ts +25 -0
  152. package/src/Logger.ts +702 -0
  153. package/src/Mailbox.ts +268 -0
  154. package/src/ManagedRuntime.ts +180 -0
  155. package/src/Match.ts +1477 -0
  156. package/src/MergeDecision.ts +95 -0
  157. package/src/MergeState.ts +172 -0
  158. package/src/MergeStrategy.ts +107 -0
  159. package/src/Metric.ts +780 -0
  160. package/src/MetricBoundaries.ts +69 -0
  161. package/src/MetricHook.ts +151 -0
  162. package/src/MetricKey.ts +224 -0
  163. package/src/MetricKeyType.ts +262 -0
  164. package/src/MetricLabel.ts +47 -0
  165. package/src/MetricPair.ts +71 -0
  166. package/src/MetricPolling.ts +148 -0
  167. package/src/MetricRegistry.ts +48 -0
  168. package/src/MetricState.ts +257 -0
  169. package/src/Micro.ts +4405 -0
  170. package/src/ModuleVersion.ts +18 -0
  171. package/src/MutableHashMap.ts +411 -0
  172. package/src/MutableHashSet.ts +706 -0
  173. package/src/MutableList.ts +297 -0
  174. package/src/MutableQueue.ts +227 -0
  175. package/src/MutableRef.ts +202 -0
  176. package/src/NonEmptyIterable.ts +32 -0
  177. package/src/Number.ts +1071 -0
  178. package/src/Option.ts +2170 -0
  179. package/src/Order.ts +373 -0
  180. package/src/Ordering.ts +111 -0
  181. package/src/ParseResult.ts +2031 -0
  182. package/src/PartitionedSemaphore.ts +200 -0
  183. package/src/Pipeable.ts +566 -0
  184. package/src/Pool.ts +204 -0
  185. package/src/Predicate.ts +1405 -0
  186. package/src/Pretty.ts +205 -0
  187. package/src/PrimaryKey.ts +23 -0
  188. package/src/PubSub.ts +182 -0
  189. package/src/Queue.ts +644 -0
  190. package/src/Random.ts +204 -0
  191. package/src/RateLimiter.ts +138 -0
  192. package/src/RcMap.ts +141 -0
  193. package/src/RcRef.ts +122 -0
  194. package/src/Readable.ts +93 -0
  195. package/src/Record.ts +1274 -0
  196. package/src/RedBlackTree.ts +421 -0
  197. package/src/Redacted.ts +144 -0
  198. package/src/Ref.ts +180 -0
  199. package/src/RegExp.ts +38 -0
  200. package/src/Reloadable.ts +127 -0
  201. package/src/Request.ts +347 -0
  202. package/src/RequestBlock.ts +118 -0
  203. package/src/RequestResolver.ts +366 -0
  204. package/src/Resource.ts +119 -0
  205. package/src/Runtime.ts +383 -0
  206. package/src/RuntimeFlags.ts +336 -0
  207. package/src/RuntimeFlagsPatch.ts +183 -0
  208. package/src/STM.ts +2045 -0
  209. package/src/Schedule.ts +2219 -0
  210. package/src/ScheduleDecision.ts +62 -0
  211. package/src/ScheduleInterval.ts +151 -0
  212. package/src/ScheduleIntervals.ts +122 -0
  213. package/src/Scheduler.ts +353 -0
  214. package/src/Schema.ts +10914 -0
  215. package/src/SchemaAST.ts +3043 -0
  216. package/src/Scope.ts +204 -0
  217. package/src/ScopedCache.ts +151 -0
  218. package/src/ScopedRef.ts +117 -0
  219. package/src/Secret.ts +88 -0
  220. package/src/SingleProducerAsyncInput.ts +67 -0
  221. package/src/Sink.ts +1461 -0
  222. package/src/SortedMap.ts +287 -0
  223. package/src/SortedSet.ts +390 -0
  224. package/src/SourceLocation.ts +108 -0
  225. package/src/Stream.ts +6468 -0
  226. package/src/StreamEmit.ts +136 -0
  227. package/src/StreamHaltStrategy.ts +123 -0
  228. package/src/Streamable.ts +45 -0
  229. package/src/String.ts +778 -0
  230. package/src/Struct.ts +243 -0
  231. package/src/Subscribable.ts +100 -0
  232. package/src/SubscriptionRef.ts +298 -0
  233. package/src/Supervisor.ts +240 -0
  234. package/src/Symbol.ts +29 -0
  235. package/src/SynchronizedRef.ts +270 -0
  236. package/src/TArray.ts +495 -0
  237. package/src/TDeferred.ts +100 -0
  238. package/src/TMap.ts +515 -0
  239. package/src/TPriorityQueue.ts +223 -0
  240. package/src/TPubSub.ts +200 -0
  241. package/src/TQueue.ts +432 -0
  242. package/src/TRandom.ts +129 -0
  243. package/src/TReentrantLock.ts +224 -0
  244. package/src/TRef.ts +178 -0
  245. package/src/TSemaphore.ts +129 -0
  246. package/src/TSet.ts +365 -0
  247. package/src/TSubscriptionRef.ts +192 -0
  248. package/src/Take.ts +258 -0
  249. package/src/TestAnnotation.ts +158 -0
  250. package/src/TestAnnotationMap.ts +119 -0
  251. package/src/TestAnnotations.ts +117 -0
  252. package/src/TestClock.ts +556 -0
  253. package/src/TestConfig.ts +47 -0
  254. package/src/TestContext.ts +36 -0
  255. package/src/TestLive.ts +53 -0
  256. package/src/TestServices.ts +390 -0
  257. package/src/TestSized.ts +55 -0
  258. package/src/Tracer.ts +182 -0
  259. package/src/Trie.ts +840 -0
  260. package/src/Tuple.ts +305 -0
  261. package/src/Types.ts +353 -0
  262. package/src/Unify.ts +113 -0
  263. package/src/UpstreamPullRequest.ts +117 -0
  264. package/src/UpstreamPullStrategy.ts +121 -0
  265. package/src/Utils.ts +809 -0
  266. package/src/index.ts +1568 -0
  267. package/src/internal/array.ts +8 -0
  268. package/src/internal/blockedRequests.ts +520 -0
  269. package/src/internal/cache.ts +733 -0
  270. package/src/internal/cause.ts +1050 -0
  271. package/src/internal/channel/channelExecutor.ts +1200 -0
  272. package/src/internal/channel/channelState.ts +134 -0
  273. package/src/internal/channel/childExecutorDecision.ts +96 -0
  274. package/src/internal/channel/continuation.ts +200 -0
  275. package/src/internal/channel/mergeDecision.ts +113 -0
  276. package/src/internal/channel/mergeState.ts +120 -0
  277. package/src/internal/channel/mergeStrategy.ts +72 -0
  278. package/src/internal/channel/singleProducerAsyncInput.ts +259 -0
  279. package/src/internal/channel/subexecutor.ts +229 -0
  280. package/src/internal/channel/upstreamPullRequest.ts +84 -0
  281. package/src/internal/channel/upstreamPullStrategy.ts +87 -0
  282. package/src/internal/channel.ts +2603 -0
  283. package/src/internal/clock.ts +95 -0
  284. package/src/internal/completedRequestMap.ts +9 -0
  285. package/src/internal/concurrency.ts +54 -0
  286. package/src/internal/config.ts +716 -0
  287. package/src/internal/configError.ts +304 -0
  288. package/src/internal/configProvider/pathPatch.ts +97 -0
  289. package/src/internal/configProvider.ts +799 -0
  290. package/src/internal/console.ts +153 -0
  291. package/src/internal/context.ts +337 -0
  292. package/src/internal/core-effect.ts +2293 -0
  293. package/src/internal/core-stream.ts +998 -0
  294. package/src/internal/core.ts +3189 -0
  295. package/src/internal/data.ts +36 -0
  296. package/src/internal/dataSource.ts +327 -0
  297. package/src/internal/dateTime.ts +1277 -0
  298. package/src/internal/defaultServices/console.ts +100 -0
  299. package/src/internal/defaultServices.ts +163 -0
  300. package/src/internal/deferred.ts +46 -0
  301. package/src/internal/differ/chunkPatch.ts +211 -0
  302. package/src/internal/differ/contextPatch.ts +232 -0
  303. package/src/internal/differ/hashMapPatch.ts +220 -0
  304. package/src/internal/differ/hashSetPatch.ts +176 -0
  305. package/src/internal/differ/orPatch.ts +311 -0
  306. package/src/internal/differ/readonlyArrayPatch.ts +210 -0
  307. package/src/internal/differ.ts +200 -0
  308. package/src/internal/doNotation.ts +80 -0
  309. package/src/internal/effect/circular.ts +895 -0
  310. package/src/internal/effectable.ts +131 -0
  311. package/src/internal/either.ts +110 -0
  312. package/src/internal/encoding/base64.ts +286 -0
  313. package/src/internal/encoding/base64Url.ts +29 -0
  314. package/src/internal/encoding/common.ts +51 -0
  315. package/src/internal/encoding/hex.ts +315 -0
  316. package/src/internal/errors.ts +7 -0
  317. package/src/internal/executionPlan.ts +114 -0
  318. package/src/internal/executionStrategy.ts +74 -0
  319. package/src/internal/fiber.ts +388 -0
  320. package/src/internal/fiberId.ts +267 -0
  321. package/src/internal/fiberMessage.ts +82 -0
  322. package/src/internal/fiberRefs/patch.ts +144 -0
  323. package/src/internal/fiberRefs.ts +297 -0
  324. package/src/internal/fiberRuntime.ts +3842 -0
  325. package/src/internal/fiberScope.ts +71 -0
  326. package/src/internal/fiberStatus.ts +119 -0
  327. package/src/internal/groupBy.ts +530 -0
  328. package/src/internal/hashMap/array.ts +49 -0
  329. package/src/internal/hashMap/bitwise.ts +32 -0
  330. package/src/internal/hashMap/config.ts +14 -0
  331. package/src/internal/hashMap/keySet.ts +8 -0
  332. package/src/internal/hashMap/node.ts +391 -0
  333. package/src/internal/hashMap.ts +586 -0
  334. package/src/internal/hashSet.ts +323 -0
  335. package/src/internal/keyedPool.ts +244 -0
  336. package/src/internal/layer/circular.ts +214 -0
  337. package/src/internal/layer.ts +1483 -0
  338. package/src/internal/logSpan.ts +20 -0
  339. package/src/internal/logger-circular.ts +24 -0
  340. package/src/internal/logger.ts +522 -0
  341. package/src/internal/mailbox.ts +561 -0
  342. package/src/internal/managedRuntime/circular.ts +6 -0
  343. package/src/internal/managedRuntime.ts +134 -0
  344. package/src/internal/matcher.ts +652 -0
  345. package/src/internal/metric/boundaries.ts +75 -0
  346. package/src/internal/metric/hook.ts +483 -0
  347. package/src/internal/metric/key.ts +167 -0
  348. package/src/internal/metric/keyType.ts +238 -0
  349. package/src/internal/metric/label.ts +41 -0
  350. package/src/internal/metric/pair.ts +48 -0
  351. package/src/internal/metric/polling.ts +149 -0
  352. package/src/internal/metric/registry.ts +187 -0
  353. package/src/internal/metric/state.ts +290 -0
  354. package/src/internal/metric.ts +577 -0
  355. package/src/internal/opCodes/cause.ts +35 -0
  356. package/src/internal/opCodes/channel.ts +83 -0
  357. package/src/internal/opCodes/channelChildExecutorDecision.ts +17 -0
  358. package/src/internal/opCodes/channelMergeDecision.ts +11 -0
  359. package/src/internal/opCodes/channelMergeState.ts +17 -0
  360. package/src/internal/opCodes/channelMergeStrategy.ts +11 -0
  361. package/src/internal/opCodes/channelState.ts +23 -0
  362. package/src/internal/opCodes/channelUpstreamPullRequest.ts +11 -0
  363. package/src/internal/opCodes/channelUpstreamPullStrategy.ts +11 -0
  364. package/src/internal/opCodes/config.ts +65 -0
  365. package/src/internal/opCodes/configError.ts +35 -0
  366. package/src/internal/opCodes/continuation.ts +11 -0
  367. package/src/internal/opCodes/deferred.ts +11 -0
  368. package/src/internal/opCodes/effect.ts +89 -0
  369. package/src/internal/opCodes/layer.ts +59 -0
  370. package/src/internal/opCodes/streamHaltStrategy.ts +23 -0
  371. package/src/internal/option.ts +80 -0
  372. package/src/internal/pool.ts +432 -0
  373. package/src/internal/pubsub.ts +1762 -0
  374. package/src/internal/query.ts +204 -0
  375. package/src/internal/queue.ts +766 -0
  376. package/src/internal/random.ts +161 -0
  377. package/src/internal/rateLimiter.ts +93 -0
  378. package/src/internal/rcMap.ts +285 -0
  379. package/src/internal/rcRef.ts +192 -0
  380. package/src/internal/redBlackTree/iterator.ts +200 -0
  381. package/src/internal/redBlackTree/node.ts +68 -0
  382. package/src/internal/redBlackTree.ts +1245 -0
  383. package/src/internal/redacted.ts +73 -0
  384. package/src/internal/ref.ts +171 -0
  385. package/src/internal/reloadable.ts +140 -0
  386. package/src/internal/request.ts +177 -0
  387. package/src/internal/resource.ts +76 -0
  388. package/src/internal/ringBuffer.ts +68 -0
  389. package/src/internal/runtime.ts +558 -0
  390. package/src/internal/runtimeFlags.ts +178 -0
  391. package/src/internal/runtimeFlagsPatch.ts +103 -0
  392. package/src/internal/schedule/decision.ts +47 -0
  393. package/src/internal/schedule/interval.ts +101 -0
  394. package/src/internal/schedule/intervals.ts +180 -0
  395. package/src/internal/schedule.ts +2199 -0
  396. package/src/internal/schema/errors.ts +191 -0
  397. package/src/internal/schema/schemaId.ts +106 -0
  398. package/src/internal/schema/util.ts +50 -0
  399. package/src/internal/scopedCache.ts +644 -0
  400. package/src/internal/scopedRef.ts +118 -0
  401. package/src/internal/secret.ts +89 -0
  402. package/src/internal/singleShotGen.ts +35 -0
  403. package/src/internal/sink.ts +2120 -0
  404. package/src/internal/stack.ts +10 -0
  405. package/src/internal/stm/core.ts +817 -0
  406. package/src/internal/stm/entry.ts +59 -0
  407. package/src/internal/stm/journal.ts +123 -0
  408. package/src/internal/stm/opCodes/stm.ts +71 -0
  409. package/src/internal/stm/opCodes/stmState.ts +17 -0
  410. package/src/internal/stm/opCodes/strategy.ts +17 -0
  411. package/src/internal/stm/opCodes/tExit.ts +29 -0
  412. package/src/internal/stm/opCodes/tryCommit.ts +11 -0
  413. package/src/internal/stm/stm.ts +1453 -0
  414. package/src/internal/stm/stmState.ts +136 -0
  415. package/src/internal/stm/tArray.ts +550 -0
  416. package/src/internal/stm/tDeferred.ts +81 -0
  417. package/src/internal/stm/tExit.ts +190 -0
  418. package/src/internal/stm/tMap.ts +824 -0
  419. package/src/internal/stm/tPriorityQueue.ts +267 -0
  420. package/src/internal/stm/tPubSub.ts +551 -0
  421. package/src/internal/stm/tQueue.ts +393 -0
  422. package/src/internal/stm/tRandom.ts +140 -0
  423. package/src/internal/stm/tReentrantLock.ts +352 -0
  424. package/src/internal/stm/tRef.ts +195 -0
  425. package/src/internal/stm/tSemaphore.ts +113 -0
  426. package/src/internal/stm/tSet.ts +259 -0
  427. package/src/internal/stm/tSubscriptionRef.ts +286 -0
  428. package/src/internal/stm/tryCommit.ts +34 -0
  429. package/src/internal/stm/txnId.ts +14 -0
  430. package/src/internal/stm/versioned.ts +4 -0
  431. package/src/internal/stream/debounceState.ts +57 -0
  432. package/src/internal/stream/emit.ts +123 -0
  433. package/src/internal/stream/haltStrategy.ts +94 -0
  434. package/src/internal/stream/handoff.ts +187 -0
  435. package/src/internal/stream/handoffSignal.ts +59 -0
  436. package/src/internal/stream/pull.ts +34 -0
  437. package/src/internal/stream/sinkEndReason.ts +30 -0
  438. package/src/internal/stream/zipAllState.ts +88 -0
  439. package/src/internal/stream/zipChunksState.ts +56 -0
  440. package/src/internal/stream.ts +8801 -0
  441. package/src/internal/string-utils.ts +107 -0
  442. package/src/internal/subscriptionRef.ts +138 -0
  443. package/src/internal/supervisor/patch.ts +190 -0
  444. package/src/internal/supervisor.ts +303 -0
  445. package/src/internal/synchronizedRef.ts +114 -0
  446. package/src/internal/take.ts +199 -0
  447. package/src/internal/testing/sleep.ts +27 -0
  448. package/src/internal/testing/suspendedWarningData.ts +85 -0
  449. package/src/internal/testing/warningData.ts +94 -0
  450. package/src/internal/tracer.ts +150 -0
  451. package/src/internal/trie.ts +722 -0
  452. package/src/internal/version.ts +7 -0
package/src/Option.ts ADDED
@@ -0,0 +1,2170 @@
1
+ /**
2
+ * @since 2.0.0
3
+ */
4
+ import type { Either } from "./Either.js"
5
+ import * as Equal from "./Equal.js"
6
+ import * as Equivalence from "./Equivalence.js"
7
+ import type { LazyArg } from "./Function.js"
8
+ import { constNull, constUndefined, dual, identity, isFunction } from "./Function.js"
9
+ import type { TypeLambda } from "./HKT.js"
10
+ import type { Inspectable } from "./Inspectable.js"
11
+ import * as doNotation from "./internal/doNotation.js"
12
+ import * as either from "./internal/either.js"
13
+ import * as option from "./internal/option.js"
14
+ import type { Order } from "./Order.js"
15
+ import * as order from "./Order.js"
16
+ import type { Pipeable } from "./Pipeable.js"
17
+ import type { Predicate, Refinement } from "./Predicate.js"
18
+ import type { Covariant, NoInfer, NotFunction } from "./Types.js"
19
+ import type * as Unify from "./Unify.js"
20
+ import * as Gen from "./Utils.js"
21
+
22
+ /**
23
+ * The `Option` data type represents optional values. An `Option<A>` can either
24
+ * be `Some<A>`, containing a value of type `A`, or `None`, representing the
25
+ * absence of a value.
26
+ *
27
+ * **When to Use**
28
+ *
29
+ * You can use `Option` in scenarios like:
30
+ *
31
+ * - Using it for initial values
32
+ * - Returning values from functions that are not defined for all possible
33
+ * inputs (referred to as “partial functions”)
34
+ * - Managing optional fields in data structures
35
+ * - Handling optional function arguments
36
+ *
37
+ * @category Models
38
+ * @since 2.0.0
39
+ */
40
+ export type Option<A> = None<A> | Some<A>
41
+
42
+ /**
43
+ * @category Symbols
44
+ * @since 2.0.0
45
+ */
46
+ export const TypeId: unique symbol = Symbol.for("effect/Option")
47
+
48
+ /**
49
+ * @category Symbols
50
+ * @since 2.0.0
51
+ */
52
+ export type TypeId = typeof TypeId
53
+
54
+ /**
55
+ * @category Models
56
+ * @since 2.0.0
57
+ */
58
+ export interface None<out A> extends Pipeable, Inspectable {
59
+ readonly _tag: "None"
60
+ readonly _op: "None"
61
+ readonly [TypeId]: {
62
+ readonly _A: Covariant<A>
63
+ }
64
+ [Unify.typeSymbol]?: unknown
65
+ [Unify.unifySymbol]?: OptionUnify<this>
66
+ [Unify.ignoreSymbol]?: OptionUnifyIgnore
67
+ }
68
+
69
+ /**
70
+ * @category Models
71
+ * @since 2.0.0
72
+ */
73
+ export interface Some<out A> extends Pipeable, Inspectable {
74
+ readonly _tag: "Some"
75
+ readonly _op: "Some"
76
+ readonly value: A
77
+ readonly [TypeId]: {
78
+ readonly _A: Covariant<A>
79
+ }
80
+ [Unify.typeSymbol]?: unknown
81
+ [Unify.unifySymbol]?: OptionUnify<this>
82
+ [Unify.ignoreSymbol]?: OptionUnifyIgnore
83
+ }
84
+
85
+ /**
86
+ * @category Models
87
+ * @since 2.0.0
88
+ */
89
+ export interface OptionUnify<A extends { [Unify.typeSymbol]?: any }> {
90
+ Option?: () => A[Unify.typeSymbol] extends Option<infer A0> | infer _ ? Option<A0> : never
91
+ }
92
+
93
+ /**
94
+ * @since 2.0.0
95
+ */
96
+ export declare namespace Option {
97
+ /**
98
+ * Extracts the type of the value contained in an `Option`.
99
+ *
100
+ * **Example** (Getting the Value Type of an Option)
101
+ *
102
+ * ```ts
103
+ * import { Option } from "effect"
104
+ *
105
+ * // Declare an Option holding a string
106
+ * declare const myOption: Option.Option<string>
107
+ *
108
+ * // Extract the type of the value within the Option
109
+ * //
110
+ * // ┌─── string
111
+ * // ▼
112
+ * type MyType = Option.Option.Value<typeof myOption>
113
+ * ```
114
+ *
115
+ * @since 2.0.0
116
+ * @category Type-level Utils
117
+ */
118
+ export type Value<T extends Option<any>> = [T] extends [Option<infer _A>] ? _A : never
119
+ }
120
+
121
+ /**
122
+ * @category Models
123
+ * @since 2.0.0
124
+ */
125
+ export interface OptionUnifyIgnore {}
126
+
127
+ /**
128
+ * @category Type Lambdas
129
+ * @since 2.0.0
130
+ */
131
+ export interface OptionTypeLambda extends TypeLambda {
132
+ readonly type: Option<this["Target"]>
133
+ }
134
+
135
+ /**
136
+ * Represents the absence of a value by creating an empty `Option`.
137
+ *
138
+ * `Option.none` returns an `Option<never>`, which is a subtype of `Option<A>`.
139
+ * This means you can use it in place of any `Option<A>` regardless of the type
140
+ * `A`.
141
+ *
142
+ * **Example** (Creating an Option with No Value)
143
+ *
144
+ * ```ts
145
+ * import { Option } from "effect"
146
+ *
147
+ * // An Option holding no value
148
+ * //
149
+ * // ┌─── Option<never>
150
+ * // ▼
151
+ * const noValue = Option.none()
152
+ *
153
+ * console.log(noValue)
154
+ * // Output: { _id: 'Option', _tag: 'None' }
155
+ * ```
156
+ *
157
+ * @see {@link some} for the opposite operation.
158
+ *
159
+ * @category Constructors
160
+ * @since 2.0.0
161
+ */
162
+ export const none = <A = never>(): Option<A> => option.none
163
+
164
+ /**
165
+ * Wraps the given value into an `Option` to represent its presence.
166
+ *
167
+ * **Example** (Creating an Option with a Value)
168
+ *
169
+ * ```ts
170
+ * import { Option } from "effect"
171
+ *
172
+ * // An Option holding the number 1
173
+ * //
174
+ * // ┌─── Option<number>
175
+ * // ▼
176
+ * const value = Option.some(1)
177
+ *
178
+ * console.log(value)
179
+ * // Output: { _id: 'Option', _tag: 'Some', value: 1 }
180
+ * ```
181
+ *
182
+ * @see {@link none} for the opposite operation.
183
+ *
184
+ * @category Constructors
185
+ * @since 2.0.0
186
+ */
187
+ export const some: <A>(value: A) => Option<A> = option.some
188
+
189
+ /**
190
+ * Determines whether the given value is an `Option`.
191
+ *
192
+ * **Details**
193
+ *
194
+ * This function checks if a value is an instance of `Option`. It returns `true`
195
+ * if the value is either `Option.some` or `Option.none`, and `false` otherwise.
196
+ * This is particularly useful when working with unknown values or when you need
197
+ * to ensure type safety in your code.
198
+ *
199
+ * @example
200
+ * ```ts
201
+ * import { Option } from "effect"
202
+ *
203
+ * console.log(Option.isOption(Option.some(1)))
204
+ * // Output: true
205
+ *
206
+ * console.log(Option.isOption(Option.none()))
207
+ * // Output: true
208
+ *
209
+ * console.log(Option.isOption({}))
210
+ * // Output: false
211
+ * ```
212
+ *
213
+ * @category Guards
214
+ * @since 2.0.0
215
+ */
216
+ export const isOption: (input: unknown) => input is Option<unknown> = option.isOption
217
+
218
+ /**
219
+ * Checks whether an `Option` represents the absence of a value (`None`).
220
+ *
221
+ * @example
222
+ * ```ts
223
+ * import { Option } from "effect"
224
+ *
225
+ * console.log(Option.isNone(Option.some(1)))
226
+ * // Output: false
227
+ *
228
+ * console.log(Option.isNone(Option.none()))
229
+ * // Output: true
230
+ * ```
231
+ *
232
+ * @see {@link isSome} for the opposite check.
233
+ *
234
+ * @category Guards
235
+ * @since 2.0.0
236
+ */
237
+ export const isNone: <A>(self: Option<A>) => self is None<A> = option.isNone
238
+
239
+ /**
240
+ * Checks whether an `Option` contains a value (`Some`).
241
+ *
242
+ * @example
243
+ * ```ts
244
+ * import { Option } from "effect"
245
+ *
246
+ * console.log(Option.isSome(Option.some(1)))
247
+ * // Output: true
248
+ *
249
+ * console.log(Option.isSome(Option.none()))
250
+ * // Output: false
251
+ * ```
252
+ *
253
+ * @see {@link isNone} for the opposite check.
254
+ *
255
+ * @category Guards
256
+ * @since 2.0.0
257
+ */
258
+ export const isSome: <A>(self: Option<A>) => self is Some<A> = option.isSome
259
+
260
+ /**
261
+ * Performs pattern matching on an `Option` to handle both `Some` and `None`
262
+ * cases.
263
+ *
264
+ * **Details**
265
+ *
266
+ * This function allows you to match against an `Option` and handle both
267
+ * scenarios: when the `Option` is `None` (i.e., contains no value), and when
268
+ * the `Option` is `Some` (i.e., contains a value). It executes one of the
269
+ * provided functions based on the case:
270
+ *
271
+ * - If the `Option` is `None`, the `onNone` function is executed and its result
272
+ * is returned.
273
+ * - If the `Option` is `Some`, the `onSome` function is executed with the
274
+ * contained value, and its result is returned.
275
+ *
276
+ * This function provides a concise and functional way to handle optional values
277
+ * without resorting to `if` or manual checks, making your code more declarative
278
+ * and readable.
279
+ *
280
+ * **Example** (Pattern Matching with Option)
281
+ *
282
+ * ```ts
283
+ * import { Option } from "effect"
284
+ *
285
+ * const foo = Option.some(1)
286
+ *
287
+ * const message = Option.match(foo, {
288
+ * onNone: () => "Option is empty",
289
+ * onSome: (value) => `Option has a value: ${value}`
290
+ * })
291
+ *
292
+ * console.log(message)
293
+ * // Output: "Option has a value: 1"
294
+ * ```
295
+ *
296
+ * @category Pattern matching
297
+ * @since 2.0.0
298
+ */
299
+ export const match: {
300
+ <B, A, C = B>(options: {
301
+ readonly onNone: LazyArg<B>
302
+ readonly onSome: (a: A) => C
303
+ }): (self: Option<A>) => B | C
304
+ <A, B, C = B>(self: Option<A>, options: {
305
+ readonly onNone: LazyArg<B>
306
+ readonly onSome: (a: A) => C
307
+ }): B | C
308
+ } = dual(
309
+ 2,
310
+ <A, B, C = B>(self: Option<A>, { onNone, onSome }: {
311
+ readonly onNone: LazyArg<B>
312
+ readonly onSome: (a: A) => C
313
+ }): B | C => isNone(self) ? onNone() : onSome(self.value)
314
+ )
315
+
316
+ /**
317
+ * Converts an `Option`-returning function into a type guard.
318
+ *
319
+ * **Details**
320
+ *
321
+ * This function transforms a function that returns an `Option` into a type
322
+ * guard, ensuring type safety when validating or narrowing types. The returned
323
+ * type guard function checks whether the input satisfies the condition defined
324
+ * in the original `Option`-returning function.
325
+ *
326
+ * If the original function returns `Option.some`, the type guard evaluates to
327
+ * `true`, confirming the input is of the desired type. If the function returns
328
+ * `Option.none`, the type guard evaluates to `false`.
329
+ *
330
+ * This utility is especially useful for validating types in union types,
331
+ * filtering arrays, or ensuring safe handling of specific subtypes.
332
+ *
333
+ * @example
334
+ * ```ts
335
+ * import { Option } from "effect"
336
+ *
337
+ * type MyData = string | number
338
+ *
339
+ * const parseString = (data: MyData): Option.Option<string> =>
340
+ * typeof data === "string" ? Option.some(data) : Option.none()
341
+ *
342
+ * // ┌─── (a: MyData) => a is string
343
+ * // ▼
344
+ * const isString = Option.toRefinement(parseString)
345
+ *
346
+ * console.log(isString("a"))
347
+ * // Output: true
348
+ *
349
+ * console.log(isString(1))
350
+ * // Output: false
351
+ * ```
352
+ *
353
+ * @category Conversions
354
+ * @since 2.0.0
355
+ */
356
+ export const toRefinement = <A, B extends A>(f: (a: A) => Option<B>): (a: A) => a is B => (a: A): a is B => isSome(f(a))
357
+
358
+ /**
359
+ * Converts an `Iterable` into an `Option`, wrapping the first element if it
360
+ * exists.
361
+ *
362
+ * **Details**
363
+ *
364
+ * This function takes an `Iterable` (e.g., an array, a generator, or any object
365
+ * implementing the `Iterable` interface) and returns an `Option` based on its
366
+ * content:
367
+ *
368
+ * - If the `Iterable` contains at least one element, the first element is
369
+ * wrapped in a `Some` and returned.
370
+ * - If the `Iterable` is empty, `None` is returned, representing the absence of
371
+ * a value.
372
+ *
373
+ * This utility is useful for safely handling collections that might be empty,
374
+ * ensuring you explicitly handle both cases where a value exists or doesn't.
375
+ *
376
+ * @example
377
+ * ```ts
378
+ * import { Option } from "effect"
379
+ *
380
+ * console.log(Option.fromIterable([1, 2, 3]))
381
+ * // Output: { _id: 'Option', _tag: 'Some', value: 1 }
382
+ *
383
+ * console.log(Option.fromIterable([]))
384
+ * // Output: { _id: 'Option', _tag: 'None' }
385
+ * ```
386
+ *
387
+ * @category Constructors
388
+ * @since 2.0.0
389
+ */
390
+ export const fromIterable = <A>(collection: Iterable<A>): Option<A> => {
391
+ for (const a of collection) {
392
+ return some(a)
393
+ }
394
+ return none()
395
+ }
396
+
397
+ /**
398
+ * Converts an `Either` into an `Option` by discarding the error and extracting
399
+ * the right value.
400
+ *
401
+ * **Details**
402
+ *
403
+ * This function takes an `Either` and returns an `Option` based on its value:
404
+ *
405
+ * - If the `Either` is a `Right`, its value is wrapped in a `Some` and
406
+ * returned.
407
+ * - If the `Either` is a `Left`, the error is discarded, and `None` is
408
+ * returned.
409
+ *
410
+ * This is particularly useful when you only care about the success case
411
+ * (`Right`) of an `Either` and want to handle the result using `Option`. By
412
+ * using this function, you can convert `Either` into a simpler structure for
413
+ * cases where error handling is not required.
414
+ *
415
+ * @example
416
+ * ```ts
417
+ * import { Either, Option } from "effect"
418
+ *
419
+ * console.log(Option.getRight(Either.right("ok")))
420
+ * // Output: { _id: 'Option', _tag: 'Some', value: 'ok' }
421
+ *
422
+ * console.log(Option.getRight(Either.left("err")))
423
+ * // Output: { _id: 'Option', _tag: 'None' }
424
+ * ```
425
+ *
426
+ * @see {@link getLeft} for the opposite operation.
427
+ *
428
+ * @category Conversions
429
+ * @since 2.0.0
430
+ */
431
+ export const getRight: <R, L>(self: Either<R, L>) => Option<R> = either.getRight
432
+
433
+ /**
434
+ * Converts an `Either` into an `Option` by discarding the right value and
435
+ * extracting the left value.
436
+ *
437
+ * **Details**
438
+ *
439
+ * This function transforms an `Either` into an `Option` as follows:
440
+ *
441
+ * - If the `Either` is a `Left`, its value is wrapped in a `Some` and returned.
442
+ * - If the `Either` is a `Right`, the value is discarded, and `None` is
443
+ * returned.
444
+ *
445
+ * This utility is useful when you only care about the error case (`Left`) of an
446
+ * `Either` and want to handle it as an `Option`. By discarding the right value,
447
+ * it simplifies error-focused workflows.
448
+ *
449
+ * @example
450
+ * ```ts
451
+ * import { Either, Option } from "effect"
452
+ *
453
+ * console.log(Option.getLeft(Either.right("ok")))
454
+ * // Output: { _id: 'Option', _tag: 'None' }
455
+ *
456
+ * console.log(Option.getLeft(Either.left("err")))
457
+ * // Output: { _id: 'Option', _tag: 'Some', value: 'err' }
458
+ * ```
459
+ *
460
+ * @see {@link getRight} for the opposite operation.
461
+ *
462
+ * @category Conversions
463
+ * @since 2.0.0
464
+ */
465
+ export const getLeft: <R, L>(self: Either<R, L>) => Option<L> = either.getLeft
466
+
467
+ /**
468
+ * Returns the value contained in the `Option` if it is `Some`, otherwise
469
+ * evaluates and returns the result of `onNone`.
470
+ *
471
+ * **Details**
472
+ *
473
+ * This function allows you to provide a fallback value or computation for when
474
+ * an `Option` is `None`. If the `Option` contains a value (`Some`), that value
475
+ * is returned. If it is empty (`None`), the `onNone` function is executed, and
476
+ * its result is returned instead.
477
+ *
478
+ * This utility is helpful for safely handling `Option` values by ensuring you
479
+ * always receive a meaningful result, whether or not the `Option` contains a
480
+ * value. It is particularly useful for providing default values or alternative
481
+ * logic when working with optional values.
482
+ *
483
+ * @example
484
+ * ```ts
485
+ * import { Option } from "effect"
486
+ *
487
+ * console.log(Option.some(1).pipe(Option.getOrElse(() => 0)))
488
+ * // Output: 1
489
+ *
490
+ * console.log(Option.none().pipe(Option.getOrElse(() => 0)))
491
+ * // Output: 0
492
+ * ```
493
+ *
494
+ * @see {@link getOrNull} for a version that returns `null` instead of executing a function.
495
+ * @see {@link getOrUndefined} for a version that returns `undefined` instead of executing a function.
496
+ *
497
+ * @category Getters
498
+ * @since 2.0.0
499
+ */
500
+ export const getOrElse: {
501
+ <B>(onNone: LazyArg<B>): <A>(self: Option<A>) => B | A
502
+ <A, B>(self: Option<A>, onNone: LazyArg<B>): A | B
503
+ } = dual(
504
+ 2,
505
+ <A, B>(self: Option<A>, onNone: LazyArg<B>): A | B => isNone(self) ? onNone() : self.value
506
+ )
507
+
508
+ /**
509
+ * Returns the provided `Option` `that` if the current `Option` (`self`) is
510
+ * `None`; otherwise, it returns `self`.
511
+ *
512
+ * **Details**
513
+ *
514
+ * This function provides a fallback mechanism for `Option` values. If the
515
+ * current `Option` is `None` (i.e., it contains no value), the `that` function
516
+ * is evaluated, and its resulting `Option` is returned. If the current `Option`
517
+ * is `Some` (i.e., it contains a value), the original `Option` is returned
518
+ * unchanged.
519
+ *
520
+ * This is particularly useful for chaining fallback values or computations,
521
+ * allowing you to provide alternative `Option` values when the first one is
522
+ * empty.
523
+ *
524
+ * @example
525
+ * ```ts
526
+ * import { Option } from "effect"
527
+ *
528
+ * console.log(Option.none().pipe(Option.orElse(() => Option.none())))
529
+ * // Output: { _id: 'Option', _tag: 'None' }
530
+ *
531
+ * console.log(Option.some("a").pipe(Option.orElse(() => Option.none())))
532
+ * // Output: { _id: 'Option', _tag: 'Some', value: 'a' }
533
+ *
534
+ * console.log(Option.none().pipe(Option.orElse(() => Option.some("b"))))
535
+ * // Output: { _id: 'Option', _tag: 'Some', value: 'b' }
536
+ *
537
+ * console.log(Option.some("a").pipe(Option.orElse(() => Option.some("b"))))
538
+ * // Output: { _id: 'Option', _tag: 'Some', value: 'a' }
539
+ * ```
540
+ *
541
+ * @category Error handling
542
+ * @since 2.0.0
543
+ */
544
+ export const orElse: {
545
+ <B>(that: LazyArg<Option<B>>): <A>(self: Option<A>) => Option<B | A>
546
+ <A, B>(self: Option<A>, that: LazyArg<Option<B>>): Option<A | B>
547
+ } = dual(
548
+ 2,
549
+ <A, B>(self: Option<A>, that: LazyArg<Option<B>>): Option<A | B> => isNone(self) ? that() : self
550
+ )
551
+
552
+ /**
553
+ * Returns the provided default value wrapped in `Some` if the current `Option`
554
+ * (`self`) is `None`; otherwise, returns `self`.
555
+ *
556
+ * **Details**
557
+ *
558
+ * This function provides a way to supply a default value for cases where an
559
+ * `Option` is `None`. If the current `Option` is empty (`None`), the `onNone`
560
+ * function is executed to compute the default value, which is then wrapped in a
561
+ * `Some`. If the current `Option` contains a value (`Some`), it is returned as
562
+ * is.
563
+ *
564
+ * This is particularly useful for handling optional values where a fallback
565
+ * default needs to be provided explicitly in case of absence.
566
+ *
567
+ * @example
568
+ * ```ts
569
+ * import { Option } from "effect"
570
+ *
571
+ * console.log(Option.none().pipe(Option.orElseSome(() => "b")))
572
+ * // Output: { _id: 'Option', _tag: 'Some', value: 'b' }
573
+ *
574
+ * console.log(Option.some("a").pipe(Option.orElseSome(() => "b")))
575
+ * // Output: { _id: 'Option', _tag: 'Some', value: 'a' }
576
+ * ```
577
+ *
578
+ * @category Error handling
579
+ * @since 2.0.0
580
+ */
581
+ export const orElseSome: {
582
+ <B>(onNone: LazyArg<B>): <A>(self: Option<A>) => Option<B | A>
583
+ <A, B>(self: Option<A>, onNone: LazyArg<B>): Option<A | B>
584
+ } = dual(
585
+ 2,
586
+ <A, B>(self: Option<A>, onNone: LazyArg<B>): Option<A | B> => isNone(self) ? some(onNone()) : self
587
+ )
588
+
589
+ /**
590
+ * Similar to {@link orElse}, but returns an `Either` wrapped in an `Option` to
591
+ * indicate the source of the value.
592
+ *
593
+ * **Details**
594
+ *
595
+ * This function allows you to provide a fallback `Option` in case the current
596
+ * `Option` (`self`) is `None`. However, unlike `orElse`, it returns the value
597
+ * wrapped in an `Either` object, providing additional information about where
598
+ * the value came from:
599
+ *
600
+ * - If the value is from the fallback `Option` (`that`), it is wrapped in an
601
+ * `Either.right`.
602
+ * - If the value is from the original `Option` (`self`), it is wrapped in an
603
+ * `Either.left`.
604
+ *
605
+ * This is especially useful when you need to differentiate between values
606
+ * originating from the primary `Option` and those coming from the fallback,
607
+ * while still maintaining the `Option`-style handling.
608
+ *
609
+ * @category Error handling
610
+ * @since 2.0.0
611
+ */
612
+ export const orElseEither: {
613
+ <B>(that: LazyArg<Option<B>>): <A>(self: Option<A>) => Option<Either<B, A>>
614
+ <A, B>(self: Option<A>, that: LazyArg<Option<B>>): Option<Either<B, A>>
615
+ } = dual(
616
+ 2,
617
+ <A, B>(self: Option<A>, that: LazyArg<Option<B>>): Option<Either<B, A>> =>
618
+ isNone(self) ? map(that(), either.right) : map(self, either.left)
619
+ )
620
+
621
+ /**
622
+ * Returns the first `Some` value found in an `Iterable` collection of
623
+ * `Option`s, or `None` if no `Some` is found.
624
+ *
625
+ * **Details**
626
+ *
627
+ * This function iterates over a collection of `Option` values and returns the
628
+ * first `Some` it encounters. If the collection contains only `None` values,
629
+ * the result will also be `None`. This utility is useful for efficiently
630
+ * finding the first valid value in a sequence of potentially empty or invalid
631
+ * options.
632
+ *
633
+ * The iteration stops as soon as a `Some` is found, making this function
634
+ * efficient for large collections.
635
+ *
636
+ * @example
637
+ * ```ts
638
+ * import { Option } from "effect"
639
+ *
640
+ * console.log(Option.firstSomeOf([
641
+ * Option.none(),
642
+ * Option.some(1),
643
+ * Option.some(2)
644
+ * ]))
645
+ * // Output: { _id: 'Option', _tag: 'Some', value: 1 }
646
+ * ```
647
+ *
648
+ * @category Error handling
649
+ * @since 2.0.0
650
+ */
651
+ export const firstSomeOf = <T, C extends Iterable<Option<T>> = Iterable<Option<T>>>(
652
+ collection: C
653
+ ): [C] extends [Iterable<Option<infer A>>] ? Option<A> : never => {
654
+ let out: Option<unknown> = none()
655
+ for (out of collection) {
656
+ if (isSome(out)) {
657
+ return out as any
658
+ }
659
+ }
660
+ return out as any
661
+ }
662
+
663
+ /**
664
+ * Converts a nullable value into an `Option`. Returns `None` if the value is
665
+ * `null` or `undefined`, otherwise wraps the value in a `Some`.
666
+ *
667
+ * @example
668
+ * ```ts
669
+ * import { Option } from "effect"
670
+ *
671
+ * console.log(Option.fromNullable(undefined))
672
+ * // Output: { _id: 'Option', _tag: 'None' }
673
+ *
674
+ * console.log(Option.fromNullable(null))
675
+ * // Output: { _id: 'Option', _tag: 'None' }
676
+ *
677
+ * console.log(Option.fromNullable(1))
678
+ * // Output: { _id: 'Option', _tag: 'Some', value: 1 }
679
+ * ```
680
+ *
681
+ * @category Conversions
682
+ * @since 2.0.0
683
+ */
684
+ export const fromNullable = <A>(
685
+ nullableValue: A
686
+ ): Option<NonNullable<A>> => (nullableValue == null ? none() : some(nullableValue as NonNullable<A>))
687
+
688
+ /**
689
+ * Lifts a function that returns `null` or `undefined` into the `Option`
690
+ * context.
691
+ *
692
+ * **Details**
693
+ *
694
+ * This function takes a function `f` that might return `null` or `undefined`
695
+ * and transforms it into a function that returns an `Option`. The resulting
696
+ * function will return:
697
+ * - `Some` if the original function produces a non-null, non-undefined value.
698
+ * - `None` if the original function produces `null` or `undefined`.
699
+ *
700
+ * @example
701
+ * ```ts
702
+ * import { Option } from "effect"
703
+ *
704
+ * const parse = (s: string): number | undefined => {
705
+ * const n = parseFloat(s)
706
+ * return isNaN(n) ? undefined : n
707
+ * }
708
+ *
709
+ * const parseOption = Option.liftNullable(parse)
710
+ *
711
+ * console.log(parseOption("1"))
712
+ * // Output: { _id: 'Option', _tag: 'Some', value: 1 }
713
+ *
714
+ * console.log(parseOption("not a number"))
715
+ * // Output: { _id: 'Option', _tag: 'None' }
716
+ * ```
717
+ *
718
+ * @category Conversions
719
+ * @since 2.0.0
720
+ */
721
+ export const liftNullable = <A extends ReadonlyArray<unknown>, B>(
722
+ f: (...a: A) => B | null | undefined
723
+ ): (...a: A) => Option<NonNullable<B>> =>
724
+ (...a) => fromNullable(f(...a))
725
+
726
+ /**
727
+ * Returns the value contained in the `Option` if it is `Some`; otherwise,
728
+ * returns `null`.
729
+ *
730
+ * **Details**
731
+ *
732
+ * This function provides a way to extract the value of an `Option` while
733
+ * falling back to `null` if the `Option` is `None`.
734
+ *
735
+ * It is particularly useful in scenarios where `null` is an acceptable
736
+ * placeholder for the absence of a value, such as when interacting with APIs or
737
+ * systems that use `null` as a default for missing values.
738
+ *
739
+ * @example
740
+ * ```ts
741
+ * import { Option } from "effect"
742
+ *
743
+ * console.log(Option.getOrNull(Option.some(1)))
744
+ * // Output: 1
745
+ *
746
+ * console.log(Option.getOrNull(Option.none()))
747
+ * // Output: null
748
+ * ```
749
+ *
750
+ * @category Getters
751
+ * @since 2.0.0
752
+ */
753
+ export const getOrNull: <A>(self: Option<A>) => A | null = getOrElse(constNull)
754
+
755
+ /**
756
+ * Returns the value contained in the `Option` if it is `Some`; otherwise,
757
+ * returns `undefined`.
758
+ *
759
+ * **Details**
760
+ *
761
+ * This function provides a way to extract the value of an `Option` while
762
+ * falling back to `undefined` if the `Option` is `None`.
763
+ *
764
+ * It is particularly useful in scenarios where `undefined` is an acceptable
765
+ * placeholder for the absence of a value, such as when interacting with APIs or
766
+ * systems that use `undefined` as a default for missing values.
767
+ *
768
+ * @example
769
+ * ```ts
770
+ * import { Option } from "effect"
771
+ *
772
+ * console.log(Option.getOrUndefined(Option.some(1)))
773
+ * // Output: 1
774
+ *
775
+ * console.log(Option.getOrUndefined(Option.none()))
776
+ * // Output: undefined
777
+ * ```
778
+ *
779
+ * @category Getters
780
+ * @since 2.0.0
781
+ */
782
+ export const getOrUndefined: <A>(self: Option<A>) => A | undefined = getOrElse(constUndefined)
783
+
784
+ /**
785
+ * Lifts a function that throws exceptions into a function that returns an
786
+ * `Option`.
787
+ *
788
+ * **Details**
789
+ *
790
+ * This utility function takes a function `f` that might throw an exception and
791
+ * transforms it into a safer function that returns an `Option`. If the original
792
+ * function executes successfully, the result is wrapped in a `Some`. If an
793
+ * exception is thrown, the result is `None`, allowing the developer to handle
794
+ * errors in a functional, type-safe way.
795
+ *
796
+ * @example
797
+ * ```ts
798
+ * import { Option } from "effect"
799
+ *
800
+ * const parse = Option.liftThrowable(JSON.parse)
801
+ *
802
+ * console.log(parse("1"))
803
+ * // Output: { _id: 'Option', _tag: 'Some', value: 1 }
804
+ *
805
+ * console.log(parse(""))
806
+ * // Output: { _id: 'Option', _tag: 'None' }
807
+ * ```
808
+ *
809
+ * @category Conversions
810
+ * @since 2.0.0
811
+ */
812
+ export const liftThrowable = <A extends ReadonlyArray<unknown>, B>(
813
+ f: (...a: A) => B
814
+ ): (...a: A) => Option<B> =>
815
+ (...a) => {
816
+ try {
817
+ return some(f(...a))
818
+ } catch {
819
+ return none()
820
+ }
821
+ }
822
+
823
+ /**
824
+ * Extracts the value of an `Option` or throws an error if the `Option` is
825
+ * `None`, using a custom error factory.
826
+ *
827
+ * **Details**
828
+ *
829
+ * This function allows you to extract the value of an `Option` when it is
830
+ * `Some`. If the `Option` is `None`, it throws an error generated by the
831
+ * provided `onNone` function. This utility is particularly useful when you need
832
+ * a fail-fast behavior for empty `Option` values and want to provide a custom
833
+ * error message or object.
834
+ *
835
+ * @example
836
+ * ```ts
837
+ * import * as assert from "node:assert"
838
+ * import { Option } from "effect"
839
+ *
840
+ * assert.deepStrictEqual(
841
+ * Option.getOrThrowWith(Option.some(1), () => new Error('Unexpected None')),
842
+ * 1
843
+ * )
844
+ * assert.throws(() => Option.getOrThrowWith(Option.none(), () => new Error('Unexpected None')))
845
+ * ```
846
+ *
847
+ * @see {@link getOrThrow} for a version that throws a default error.
848
+ *
849
+ * @category Conversions
850
+ * @since 2.0.0
851
+ */
852
+ export const getOrThrowWith: {
853
+ (onNone: () => unknown): <A>(self: Option<A>) => A
854
+ <A>(self: Option<A>, onNone: () => unknown): A
855
+ } = dual(2, <A>(self: Option<A>, onNone: () => unknown): A => {
856
+ if (isSome(self)) {
857
+ return self.value
858
+ }
859
+ throw onNone()
860
+ })
861
+
862
+ /**
863
+ * Extracts the value of an `Option` or throws a default error if the `Option`
864
+ * is `None`.
865
+ *
866
+ * **Details**
867
+ *
868
+ * This function extracts the value from an `Option` if it is `Some`. If the
869
+ * `Option` is `None`, it throws a default error. It is useful for fail-fast
870
+ * scenarios where the absence of a value is treated as an exceptional case and
871
+ * a default error is sufficient.
872
+ *
873
+ * @example
874
+ * ```ts
875
+ * import * as assert from "node:assert"
876
+ * import { Option } from "effect"
877
+ *
878
+ * assert.deepStrictEqual(Option.getOrThrow(Option.some(1)), 1)
879
+ * assert.throws(() => Option.getOrThrow(Option.none()))
880
+ * ```
881
+ *
882
+ * @see {@link getOrThrowWith} for a version that allows you to provide a custom error.
883
+ *
884
+ * @category Conversions
885
+ * @since 2.0.0
886
+ */
887
+ export const getOrThrow: <A>(self: Option<A>) => A = getOrThrowWith(() => new Error("getOrThrow called on a None"))
888
+
889
+ /**
890
+ * Transforms the value inside a `Some` to a new value using the provided
891
+ * function, while leaving `None` unchanged.
892
+ *
893
+ * **Details**
894
+ *
895
+ * This function applies a mapping function `f` to the value inside an `Option`
896
+ * if it is a `Some`. If the `Option` is `None`, it remains unchanged. The
897
+ * result is a new `Option` with the transformed value (if it was a `Some`) or
898
+ * still `None`.
899
+ *
900
+ * This utility is particularly useful for chaining transformations in a
901
+ * functional way without needing to manually handle `None` cases.
902
+ *
903
+ * @example
904
+ * ```ts
905
+ * import { Option } from "effect"
906
+ *
907
+ * // Mapping over a `Some`
908
+ * const someValue = Option.some(2)
909
+ *
910
+ * console.log(Option.map(someValue, (n) => n * 2))
911
+ * // Output: { _id: 'Option', _tag: 'Some', value: 4 }
912
+ *
913
+ * // Mapping over a `None`
914
+ * const noneValue = Option.none<number>()
915
+ *
916
+ * console.log(Option.map(noneValue, (n) => n * 2))
917
+ * // Output: { _id: 'Option', _tag: 'None' }
918
+ * ```
919
+ *
920
+ * @category Mapping
921
+ * @since 2.0.0
922
+ */
923
+ export const map: {
924
+ <A, B>(f: (a: A) => B): (self: Option<A>) => Option<B>
925
+ <A, B>(self: Option<A>, f: (a: A) => B): Option<B>
926
+ } = dual(
927
+ 2,
928
+ <A, B>(self: Option<A>, f: (a: A) => B): Option<B> => isNone(self) ? none() : some(f(self.value))
929
+ )
930
+
931
+ /**
932
+ * Replaces the value inside a `Some` with the specified constant value, leaving
933
+ * `None` unchanged.
934
+ *
935
+ * **Details**
936
+ *
937
+ * This function transforms an `Option` by replacing the value inside a `Some`
938
+ * with the given constant value `b`. If the `Option` is `None`, it remains
939
+ * unchanged.
940
+ *
941
+ * This is useful when you want to preserve the presence of a value (`Some`) but
942
+ * replace its content with a fixed value.
943
+ *
944
+ * @example
945
+ * ```ts
946
+ * import { Option } from "effect"
947
+ *
948
+ * // Replacing the value of a `Some`
949
+ * const someValue = Option.some(42)
950
+ *
951
+ * console.log(Option.as(someValue, "new value"))
952
+ * // Output: { _id: 'Option', _tag: 'Some', value: 'new value' }
953
+ *
954
+ * // Replacing a `None` (no effect)
955
+ * const noneValue = Option.none<number>()
956
+ *
957
+ * console.log(Option.as(noneValue, "new value"))
958
+ * // Output: { _id: 'Option', _tag: 'None' }
959
+ * ```
960
+ *
961
+ * @category Mapping
962
+ * @since 2.0.0
963
+ */
964
+ export const as: {
965
+ <B>(b: B): <X>(self: Option<X>) => Option<B>
966
+ <X, B>(self: Option<X>, b: B): Option<B>
967
+ } = dual(2, <X, B>(self: Option<X>, b: B): Option<B> => map(self, () => b))
968
+
969
+ /**
970
+ * Replaces the value inside a `Some` with the constant value `void`, leaving
971
+ * `None` unchanged.
972
+ *
973
+ * **Details**
974
+ *
975
+ * This function transforms an `Option` by replacing the value inside a `Some`
976
+ * with `void`. If the `Option` is `None`, it remains unchanged.
977
+ *
978
+ * This is particularly useful in scenarios where the presence or absence of a
979
+ * value is significant, but the actual content of the value is irrelevant.
980
+ *
981
+ * @category Mapping
982
+ * @since 2.0.0
983
+ */
984
+ export const asVoid: <_>(self: Option<_>) => Option<void> = as(undefined)
985
+
986
+ const void_: Option<void> = some(undefined)
987
+ export {
988
+ /**
989
+ * @since 2.0.0
990
+ */
991
+ void_ as void
992
+ }
993
+
994
+ /**
995
+ * Applies a function to the value of a `Some` and flattens the resulting
996
+ * `Option`. If the input is `None`, it remains `None`.
997
+ *
998
+ * **Details**
999
+ *
1000
+ * This function allows you to chain computations that return `Option` values.
1001
+ * If the input `Option` is `Some`, the provided function `f` is applied to the
1002
+ * contained value, and the resulting `Option` is returned. If the input is
1003
+ * `None`, the function is not applied, and the result remains `None`.
1004
+ *
1005
+ * This utility is particularly useful for sequencing operations that may fail
1006
+ * or produce optional results, enabling clean and concise workflows for
1007
+ * handling such cases.
1008
+ *
1009
+ * @example
1010
+ * ```ts
1011
+ * import { Option } from "effect"
1012
+ *
1013
+ * interface Address {
1014
+ * readonly city: string
1015
+ * readonly street: Option.Option<string>
1016
+ * }
1017
+ *
1018
+ * interface User {
1019
+ * readonly id: number
1020
+ * readonly username: string
1021
+ * readonly email: Option.Option<string>
1022
+ * readonly address: Option.Option<Address>
1023
+ * }
1024
+ *
1025
+ * const user: User = {
1026
+ * id: 1,
1027
+ * username: "john_doe",
1028
+ * email: Option.some("john.doe@example.com"),
1029
+ * address: Option.some({
1030
+ * city: "New York",
1031
+ * street: Option.some("123 Main St")
1032
+ * })
1033
+ * }
1034
+ *
1035
+ * // Use flatMap to extract the street value
1036
+ * const street = user.address.pipe(
1037
+ * Option.flatMap((address) => address.street)
1038
+ * )
1039
+ *
1040
+ * console.log(street)
1041
+ * // Output: { _id: 'Option', _tag: 'Some', value: '123 Main St' }
1042
+ * ```
1043
+ *
1044
+ * @category Sequencing
1045
+ * @since 2.0.0
1046
+ */
1047
+ export const flatMap: {
1048
+ <A, B>(f: (a: A) => Option<B>): (self: Option<A>) => Option<B>
1049
+ <A, B>(self: Option<A>, f: (a: A) => Option<B>): Option<B>
1050
+ } = dual(
1051
+ 2,
1052
+ <A, B>(self: Option<A>, f: (a: A) => Option<B>): Option<B> => isNone(self) ? none() : f(self.value)
1053
+ )
1054
+
1055
+ /**
1056
+ * Chains two `Option`s together. The second `Option` can either be a static
1057
+ * value or depend on the result of the first `Option`.
1058
+ *
1059
+ * **Details**
1060
+ *
1061
+ * This function enables sequencing of two `Option` computations. If the first
1062
+ * `Option` is `Some`, the second `Option` is evaluated. The second `Option` can
1063
+ * either:
1064
+ *
1065
+ * - Be a static `Option` value.
1066
+ * - Be a function that produces an `Option`, optionally based on the value of
1067
+ * the first `Option`.
1068
+ *
1069
+ * If the first `Option` is `None`, the function skips the evaluation of the
1070
+ * second `Option` and directly returns `None`.
1071
+ *
1072
+ * @category Sequencing
1073
+ * @since 2.0.0
1074
+ */
1075
+ export const andThen: {
1076
+ <A, B>(f: (a: A) => Option<B>): (self: Option<A>) => Option<B>
1077
+ <B>(f: Option<B>): <A>(self: Option<A>) => Option<B>
1078
+ <A, B>(f: (a: A) => B): (self: Option<A>) => Option<B>
1079
+ <B>(f: NotFunction<B>): <A>(self: Option<A>) => Option<B>
1080
+ <A, B>(self: Option<A>, f: (a: A) => Option<B>): Option<B>
1081
+ <A, B>(self: Option<A>, f: Option<B>): Option<B>
1082
+ <A, B>(self: Option<A>, f: (a: A) => B): Option<B>
1083
+ <A, B>(self: Option<A>, f: NotFunction<B>): Option<B>
1084
+ } = dual(
1085
+ 2,
1086
+ <A, B>(self: Option<A>, f: (a: A) => Option<B> | Option<B>): Option<B> =>
1087
+ flatMap(self, (a) => {
1088
+ const b = isFunction(f) ? f(a) : f
1089
+ return isOption(b) ? b : some(b)
1090
+ })
1091
+ )
1092
+
1093
+ /**
1094
+ * Combines `flatMap` and `fromNullable`, transforming the value inside a `Some`
1095
+ * using a function that may return `null` or `undefined`.
1096
+ *
1097
+ * **Details**
1098
+ *
1099
+ * This function applies a transformation function `f` to the value inside a
1100
+ * `Some`. The function `f` may return a value, `null`, or `undefined`. If `f`
1101
+ * returns a value, it is wrapped in a `Some`. If `f` returns `null` or
1102
+ * `undefined`, the result is `None`. If the input `Option` is `None`, the
1103
+ * function is not applied, and `None` is returned.
1104
+ *
1105
+ * This utility is particularly useful when working with deeply nested optional
1106
+ * values or chaining computations that may result in `null` or `undefined` at
1107
+ * some point.
1108
+ *
1109
+ * @example
1110
+ * ```ts
1111
+ * import { Option } from "effect"
1112
+ *
1113
+ * interface Employee {
1114
+ * company?: {
1115
+ * address?: {
1116
+ * street?: {
1117
+ * name?: string
1118
+ * }
1119
+ * }
1120
+ * }
1121
+ * }
1122
+ *
1123
+ * const employee1: Employee = { company: { address: { street: { name: "high street" } } } }
1124
+ *
1125
+ * // Extracting a deeply nested property
1126
+ * console.log(
1127
+ * Option.some(employee1)
1128
+ * .pipe(Option.flatMapNullable((employee) => employee.company?.address?.street?.name))
1129
+ * )
1130
+ * // Output: { _id: 'Option', _tag: 'Some', value: 'high street' }
1131
+ *
1132
+ * const employee2: Employee = { company: { address: { street: {} } } }
1133
+ *
1134
+ * // Property does not exist
1135
+ * console.log(
1136
+ * Option.some(employee2)
1137
+ * .pipe(Option.flatMapNullable((employee) => employee.company?.address?.street?.name))
1138
+ * )
1139
+ * // Output: { _id: 'Option', _tag: 'None' }
1140
+ * ```
1141
+ *
1142
+ * @category Sequencing
1143
+ * @since 2.0.0
1144
+ */
1145
+ export const flatMapNullable: {
1146
+ <A, B>(f: (a: A) => B | null | undefined): (self: Option<A>) => Option<NonNullable<B>>
1147
+ <A, B>(self: Option<A>, f: (a: A) => B | null | undefined): Option<NonNullable<B>>
1148
+ } = dual(
1149
+ 2,
1150
+ <A, B>(self: Option<A>, f: (a: A) => B | null | undefined): Option<NonNullable<B>> =>
1151
+ isNone(self) ? none() : fromNullable(f(self.value))
1152
+ )
1153
+
1154
+ /**
1155
+ * Flattens an `Option` of `Option` into a single `Option`.
1156
+ *
1157
+ * **Details**
1158
+ *
1159
+ * This function takes an `Option` that wraps another `Option` and flattens it
1160
+ * into a single `Option`. If the outer `Option` is `Some`, the function
1161
+ * extracts the inner `Option`. If the outer `Option` is `None`, the result
1162
+ * remains `None`.
1163
+ *
1164
+ * This is useful for simplifying nested `Option` structures that may arise
1165
+ * during functional operations.
1166
+ *
1167
+ * @category Sequencing
1168
+ * @since 2.0.0
1169
+ */
1170
+ export const flatten: <A>(self: Option<Option<A>>) => Option<A> = flatMap(identity)
1171
+
1172
+ /**
1173
+ * Combines two `Option`s, keeping the value from the second `Option` if both
1174
+ * are `Some`.
1175
+ *
1176
+ * **Details**
1177
+ *
1178
+ * This function takes two `Option`s and returns the second one if the first is
1179
+ * `Some`. If the first `Option` is `None`, the result will also be `None`,
1180
+ * regardless of the second `Option`. It effectively "zips" the two `Option`s
1181
+ * while discarding the value from the first `Option`.
1182
+ *
1183
+ * This is particularly useful when sequencing computations where the result of
1184
+ * the first computation is not needed, and you only care about the result of
1185
+ * the second computation.
1186
+ *
1187
+ * @category Zipping
1188
+ * @since 2.0.0
1189
+ */
1190
+ export const zipRight: {
1191
+ <B>(that: Option<B>): <_>(self: Option<_>) => Option<B>
1192
+ <X, B>(self: Option<X>, that: Option<B>): Option<B>
1193
+ } = dual(2, <X, B>(self: Option<X>, that: Option<B>): Option<B> => flatMap(self, () => that))
1194
+
1195
+ /**
1196
+ * Combines two `Option`s, keeping the value from the first `Option` if both are
1197
+ * `Some`.
1198
+ *
1199
+ * **Details**
1200
+ *
1201
+ * This function takes two `Option`s and returns the first one if it is `Some`.
1202
+ * If either the first `Option` or the second `Option` is `None`, the result
1203
+ * will be `None`. This operation "zips" the two `Option`s while discarding the
1204
+ * value from the second `Option`.
1205
+ *
1206
+ * This is useful when sequencing computations where the second `Option`
1207
+ * represents a dependency or condition that must hold, but its value is
1208
+ * irrelevant.
1209
+ *
1210
+ * @category Zipping
1211
+ * @since 2.0.0
1212
+ */
1213
+ export const zipLeft: {
1214
+ <_>(that: Option<_>): <A>(self: Option<A>) => Option<A>
1215
+ <A, X>(self: Option<A>, that: Option<X>): Option<A>
1216
+ } = dual(2, <A, X>(self: Option<A>, that: Option<X>): Option<A> => tap(self, () => that))
1217
+
1218
+ /**
1219
+ * Composes two functions that return `Option` values, creating a new function
1220
+ * that chains them together.
1221
+ *
1222
+ * **Details**
1223
+ *
1224
+ * This function allows you to compose two computations, each represented by a
1225
+ * function that returns an `Option`. The result of the first function is passed
1226
+ * to the second function if it is `Some`. If the first function returns `None`,
1227
+ * the composed function short-circuits and returns `None` without invoking the
1228
+ * second function.
1229
+ *
1230
+ * @example
1231
+ * ```ts
1232
+ * import { Option } from "effect"
1233
+ *
1234
+ * const parse = (s: string): Option.Option<number> => isNaN(Number(s)) ? Option.none() : Option.some(Number(s))
1235
+ *
1236
+ * const double = (n: number): Option.Option<number> => n > 0 ? Option.some(n * 2) : Option.none()
1237
+ *
1238
+ * const parseAndDouble = Option.composeK(parse, double)
1239
+ *
1240
+ * console.log(parseAndDouble("42"))
1241
+ * // Output: { _id: 'Option', _tag: 'Some', value: 84 }
1242
+ *
1243
+ * console.log(parseAndDouble("not a number"))
1244
+ * // Output: { _id: 'Option', _tag: 'None' }
1245
+ * ```
1246
+ *
1247
+ * @category Sequencing
1248
+ * @since 2.0.0
1249
+ */
1250
+ export const composeK: {
1251
+ <B, C>(bfc: (b: B) => Option<C>): <A>(afb: (a: A) => Option<B>) => (a: A) => Option<C>
1252
+ <A, B, C>(afb: (a: A) => Option<B>, bfc: (b: B) => Option<C>): (a: A) => Option<C>
1253
+ } = dual(2, <A, B, C>(afb: (a: A) => Option<B>, bfc: (b: B) => Option<C>) => (a: A): Option<C> => flatMap(afb(a), bfc))
1254
+
1255
+ /**
1256
+ * Applies the provided function `f` to the value of the `Option` if it is
1257
+ * `Some` and returns the original `Option`, unless `f` returns `None`, in which
1258
+ * case it returns `None`.
1259
+ *
1260
+ * **Details**
1261
+ *
1262
+ * This function allows you to perform additional computations on the value of
1263
+ * an `Option` without modifying its original value. If the `Option` is `Some`,
1264
+ * the provided function `f` is executed with the value, and its result
1265
+ * determines whether the original `Option` is returned (`Some`) or the result
1266
+ * is `None` if `f` returns `None`. If the input `Option` is `None`, the
1267
+ * function is not executed, and `None` is returned.
1268
+ *
1269
+ * This is particularly useful for applying side conditions or performing
1270
+ * validation checks while retaining the original `Option`'s value.
1271
+ *
1272
+ * @example
1273
+ * ```ts
1274
+ * import { Option } from "effect"
1275
+ *
1276
+ * const getInteger = (n: number) => Number.isInteger(n) ? Option.some(n) : Option.none()
1277
+ *
1278
+ * console.log(Option.tap(Option.none(), getInteger))
1279
+ * // Output: { _id: 'Option', _tag: 'None' }
1280
+ *
1281
+ * console.log(Option.tap(Option.some(1), getInteger))
1282
+ * // Output: { _id: 'Option', _tag: 'Some', value: 1 }
1283
+ *
1284
+ * console.log(Option.tap(Option.some(1.14), getInteger))
1285
+ * // Output: { _id: 'Option', _tag: 'None' }
1286
+ * ```
1287
+ *
1288
+ * @category Sequencing
1289
+ * @since 2.0.0
1290
+ */
1291
+ export const tap: {
1292
+ <A, X>(f: (a: A) => Option<X>): (self: Option<A>) => Option<A>
1293
+ <A, X>(self: Option<A>, f: (a: A) => Option<X>): Option<A>
1294
+ } = dual(2, <A, X>(self: Option<A>, f: (a: A) => Option<X>): Option<A> => flatMap(self, (a) => map(f(a), () => a)))
1295
+
1296
+ /**
1297
+ * Combines two `Option` values into a single `Option` containing a tuple of
1298
+ * their values if both are `Some`.
1299
+ *
1300
+ * **Details**
1301
+ *
1302
+ * This function takes two `Option`s and combines their values into a tuple `[A,
1303
+ * B]` if both are `Some`. If either of the `Option`s is `None`, the result is
1304
+ * `None`. This is particularly useful for combining multiple `Option` values
1305
+ * into a single one, ensuring both contain valid values.
1306
+ *
1307
+ * @category Combining
1308
+ * @since 2.0.0
1309
+ */
1310
+ export const product = <A, B>(self: Option<A>, that: Option<B>): Option<[A, B]> =>
1311
+ isSome(self) && isSome(that) ? some([self.value, that.value]) : none()
1312
+
1313
+ /**
1314
+ * Combines an `Option` with a collection of `Option`s into a single `Option`
1315
+ * containing a tuple of their values if all are `Some`.
1316
+ *
1317
+ * **Details**
1318
+ *
1319
+ * This function takes a primary `Option` and a collection of `Option`s and
1320
+ * combines their values into a tuple `[A, ...Array<A>]` if all are `Some`. If
1321
+ * the primary `Option` or any `Option` in the collection is `None`, the result
1322
+ * is `None`.
1323
+ *
1324
+ * @category Combining
1325
+ * @since 2.0.0
1326
+ */
1327
+ export const productMany = <A>(
1328
+ self: Option<A>,
1329
+ collection: Iterable<Option<A>>
1330
+ ): Option<[A, ...Array<A>]> => {
1331
+ if (isNone(self)) {
1332
+ return none()
1333
+ }
1334
+ const out: [A, ...Array<A>] = [self.value]
1335
+ for (const o of collection) {
1336
+ if (isNone(o)) {
1337
+ return none()
1338
+ }
1339
+ out.push(o.value)
1340
+ }
1341
+ return some(out)
1342
+ }
1343
+
1344
+ /**
1345
+ * Combines a structure of `Option`s into a single `Option` containing the
1346
+ * values with the same structure.
1347
+ *
1348
+ * **Details**
1349
+ *
1350
+ * This function takes a structure of `Option`s (a tuple, struct, or iterable)
1351
+ * and produces a single `Option` that contains the values from the input
1352
+ * structure if all `Option`s are `Some`. If any `Option` in the input is
1353
+ * `None`, the result is `None`. The structure of the input is preserved in the
1354
+ * output.
1355
+ *
1356
+ * - If the input is a tuple (e.g., an array), the result will be an `Option`
1357
+ * containing a tuple with the same length.
1358
+ * - If the input is a struct (e.g., an object), the result will be an `Option`
1359
+ * containing a struct with the same keys.
1360
+ * - If the input is an iterable, the result will be an `Option` containing an
1361
+ * array.
1362
+ *
1363
+ * @example
1364
+ * ```ts
1365
+ * import { Option } from "effect"
1366
+ *
1367
+ * const maybeName: Option.Option<string> = Option.some("John")
1368
+ * const maybeAge: Option.Option<number> = Option.some(25)
1369
+ *
1370
+ * // ┌─── Option<[string, number]>
1371
+ * // ▼
1372
+ * const tuple = Option.all([maybeName, maybeAge])
1373
+ * console.log(tuple)
1374
+ * // Output:
1375
+ * // { _id: 'Option', _tag: 'Some', value: [ 'John', 25 ] }
1376
+ *
1377
+ * // ┌─── Option<{ name: string; age: number; }>
1378
+ * // ▼
1379
+ * const struct = Option.all({ name: maybeName, age: maybeAge })
1380
+ * console.log(struct)
1381
+ * // Output:
1382
+ * // { _id: 'Option', _tag: 'Some', value: { name: 'John', age: 25 } }
1383
+ * ```
1384
+ *
1385
+ * @category Combining
1386
+ * @since 2.0.0
1387
+ */
1388
+ // @ts-expect-error
1389
+ export const all: <const I extends Iterable<Option<any>> | Record<string, Option<any>>>(
1390
+ input: I
1391
+ ) => [I] extends [ReadonlyArray<Option<any>>] ? Option<
1392
+ { -readonly [K in keyof I]: [I[K]] extends [Option<infer A>] ? A : never }
1393
+ >
1394
+ : [I] extends [Iterable<Option<infer A>>] ? Option<Array<A>>
1395
+ : Option<{ -readonly [K in keyof I]: [I[K]] extends [Option<infer A>] ? A : never }> = (
1396
+ input: Iterable<Option<any>> | Record<string, Option<any>>
1397
+ ): Option<any> => {
1398
+ if (Symbol.iterator in input) {
1399
+ const out: Array<Option<any>> = []
1400
+ for (const o of (input as Iterable<Option<any>>)) {
1401
+ if (isNone(o)) {
1402
+ return none()
1403
+ }
1404
+ out.push(o.value)
1405
+ }
1406
+ return some(out)
1407
+ }
1408
+
1409
+ const out: Record<string, any> = {}
1410
+ for (const key of Object.keys(input)) {
1411
+ const o = input[key]
1412
+ if (isNone(o)) {
1413
+ return none()
1414
+ }
1415
+ out[key] = o.value
1416
+ }
1417
+ return some(out)
1418
+ }
1419
+
1420
+ /**
1421
+ * Combines two `Option` values into a new `Option` by applying a provided
1422
+ * function to their values.
1423
+ *
1424
+ * **Details**
1425
+ *
1426
+ * This function takes two `Option` values (`self` and `that`) and a combining
1427
+ * function `f`. If both `Option` values are `Some`, the function `f` is applied
1428
+ * to their values, and the result is wrapped in a new `Some`. If either
1429
+ * `Option` is `None`, the result is `None`.
1430
+ *
1431
+ * This utility is useful for combining two optional computations into a single
1432
+ * result while maintaining type safety and avoiding explicit checks for `None`.
1433
+ *
1434
+ * @example
1435
+ * ```ts
1436
+ * import { Option } from "effect"
1437
+ *
1438
+ * const maybeName: Option.Option<string> = Option.some("John")
1439
+ * const maybeAge: Option.Option<number> = Option.some(25)
1440
+ *
1441
+ * // Combine the name and age into a person object
1442
+ * const person = Option.zipWith(maybeName, maybeAge, (name, age) => ({
1443
+ * name: name.toUpperCase(),
1444
+ * age
1445
+ * }))
1446
+ *
1447
+ * console.log(person)
1448
+ * // Output:
1449
+ * // { _id: 'Option', _tag: 'Some', value: { name: 'JOHN', age: 25 } }
1450
+ * ```
1451
+ *
1452
+ * @category Zipping
1453
+ * @since 2.0.0
1454
+ */
1455
+ export const zipWith: {
1456
+ <B, A, C>(that: Option<B>, f: (a: A, b: B) => C): (self: Option<A>) => Option<C>
1457
+ <A, B, C>(self: Option<A>, that: Option<B>, f: (a: A, b: B) => C): Option<C>
1458
+ } = dual(
1459
+ 3,
1460
+ <A, B, C>(self: Option<A>, that: Option<B>, f: (a: A, b: B) => C): Option<C> =>
1461
+ map(product(self, that), ([a, b]) => f(a, b))
1462
+ )
1463
+
1464
+ /**
1465
+ * Applies a function inside a `Some` to a value inside another `Some`,
1466
+ * combining them into a new `Option`.
1467
+ *
1468
+ * **Details**
1469
+ *
1470
+ * This function allows you to apply a function wrapped in an `Option` (`self`)
1471
+ * to a value wrapped in another `Option` (`that`). If both `Option`s are
1472
+ * `Some`, the function is applied to the value, and the result is wrapped in a
1473
+ * new `Some`. If either `Option` is `None`, the result is `None`.
1474
+ *
1475
+ * @category Combining
1476
+ * @since 2.0.0
1477
+ */
1478
+ export const ap: {
1479
+ <A>(that: Option<A>): <B>(self: Option<(a: A) => B>) => Option<B>
1480
+ <A, B>(self: Option<(a: A) => B>, that: Option<A>): Option<B>
1481
+ } = dual(2, <A, B>(self: Option<(a: A) => B>, that: Option<A>): Option<B> => zipWith(self, that, (f, a) => f(a)))
1482
+
1483
+ /**
1484
+ * Reduces an `Iterable` of `Option<A>` to a single value of type `B`, ignoring
1485
+ * elements that are `None`.
1486
+ *
1487
+ * **Details**
1488
+ *
1489
+ * This function takes an initial value of type `B` and a reducing function `f`
1490
+ * that combines the accumulator with values of type `A`. It processes an
1491
+ * iterable of `Option<A>`, applying `f` only to the `Some` values while
1492
+ * ignoring the `None` values. The result is a single value of type `B`.
1493
+ *
1494
+ * This utility is particularly useful for aggregating values from an iterable
1495
+ * of `Option`s while skipping the absent (`None`) values.
1496
+ *
1497
+ * @example
1498
+ * ```ts
1499
+ * import { Option, pipe } from "effect"
1500
+ *
1501
+ * const iterable = [Option.some(1), Option.none(), Option.some(2), Option.none()]
1502
+ *
1503
+ * console.log(pipe(iterable, Option.reduceCompact(0, (b, a) => b + a)))
1504
+ * // Output: 3
1505
+ * ```
1506
+ *
1507
+ * @category Reducing
1508
+ * @since 2.0.0
1509
+ */
1510
+ export const reduceCompact: {
1511
+ <B, A>(b: B, f: (b: B, a: A) => B): (self: Iterable<Option<A>>) => B
1512
+ <A, B>(self: Iterable<Option<A>>, b: B, f: (b: B, a: A) => B): B
1513
+ } = dual(
1514
+ 3,
1515
+ <A, B>(self: Iterable<Option<A>>, b: B, f: (b: B, a: A) => B): B => {
1516
+ let out: B = b
1517
+ for (const oa of self) {
1518
+ if (isSome(oa)) {
1519
+ out = f(out, oa.value)
1520
+ }
1521
+ }
1522
+ return out
1523
+ }
1524
+ )
1525
+
1526
+ /**
1527
+ * Converts an `Option` into an `Array`.
1528
+ * If the input is `None`, an empty array is returned.
1529
+ * If the input is `Some`, its value is wrapped in a single-element array.
1530
+ *
1531
+ * @example
1532
+ * ```ts
1533
+ * import { Option } from "effect"
1534
+ *
1535
+ * console.log(Option.toArray(Option.some(1)))
1536
+ * // Output: [1]
1537
+ *
1538
+ * console.log(Option.toArray(Option.none()))
1539
+ * // Output: []
1540
+ * ```
1541
+ *
1542
+ * @category Conversions
1543
+ * @since 2.0.0
1544
+ */
1545
+ export const toArray = <A>(self: Option<A>): Array<A> => isNone(self) ? [] : [self.value]
1546
+
1547
+ /**
1548
+ * Splits an `Option` into two `Option`s based on the result of a mapping
1549
+ * function that produces an `Either`.
1550
+ *
1551
+ * **Details**
1552
+ *
1553
+ * This function takes an `Option` and a mapping function `f` that converts its
1554
+ * value into an `Either`. It returns a tuple of two `Option`s:
1555
+ *
1556
+ * - The first `Option` (`left`) contains the value from the `Left` side of the
1557
+ * `Either` if it exists, otherwise `None`.
1558
+ * - The second `Option` (`right`) contains the value from the `Right` side of
1559
+ * the `Either` if it exists, otherwise `None`.
1560
+ *
1561
+ * If the input `Option` is `None`, both returned `Option`s are `None`.
1562
+ *
1563
+ * This utility is useful for filtering and categorizing the contents of an
1564
+ * `Option` based on a bifurcating computation.
1565
+ *
1566
+ * @category Filtering
1567
+ * @since 2.0.0
1568
+ */
1569
+ export const partitionMap: {
1570
+ <A, B, C>(f: (a: A) => Either<C, B>): (self: Option<A>) => [left: Option<B>, right: Option<C>]
1571
+ <A, B, C>(self: Option<A>, f: (a: A) => Either<C, B>): [left: Option<B>, right: Option<C>]
1572
+ } = dual(2, <A, B, C>(
1573
+ self: Option<A>,
1574
+ f: (a: A) => Either<C, B>
1575
+ ): [excluded: Option<B>, satisfying: Option<C>] => {
1576
+ if (isNone(self)) {
1577
+ return [none(), none()]
1578
+ }
1579
+ const e = f(self.value)
1580
+ return either.isLeft(e) ? [some(e.left), none()] : [none(), some(e.right)]
1581
+ })
1582
+
1583
+ // TODO(4.0): remove?
1584
+ /**
1585
+ * Alias of {@link flatMap}.
1586
+ *
1587
+ * @example
1588
+ * ```ts
1589
+ * import { Option } from "effect"
1590
+ *
1591
+ * // Transform and filter numbers
1592
+ * const transformEven = (n: Option.Option<number>): Option.Option<string> =>
1593
+ * Option.filterMap(n, (n) => (n % 2 === 0 ? Option.some(`Even: ${n}`) : Option.none()))
1594
+ *
1595
+ * console.log(transformEven(Option.none()))
1596
+ * // Output: { _id: 'Option', _tag: 'None' }
1597
+ *
1598
+ * console.log(transformEven(Option.some(1)))
1599
+ * // Output: { _id: 'Option', _tag: 'None' }
1600
+ *
1601
+ * console.log(transformEven(Option.some(2)))
1602
+ * // Output: { _id: 'Option', _tag: 'Some', value: 'Even: 2' }
1603
+ * ```
1604
+ *
1605
+ * @category Filtering
1606
+ * @since 2.0.0
1607
+ */
1608
+ export const filterMap: {
1609
+ <A, B>(f: (a: A) => Option<B>): (self: Option<A>) => Option<B>
1610
+ <A, B>(self: Option<A>, f: (a: A) => Option<B>): Option<B>
1611
+ } = flatMap
1612
+
1613
+ /**
1614
+ * Filters an `Option` using a predicate. If the predicate is not satisfied or the `Option` is `None` returns `None`.
1615
+ *
1616
+ * If you need to change the type of the `Option` in addition to filtering, see `filterMap`.
1617
+ *
1618
+ * @example
1619
+ * ```ts
1620
+ * import { Option } from "effect"
1621
+ *
1622
+ * const removeEmptyString = (input: Option.Option<string>) =>
1623
+ * Option.filter(input, (value) => value !== "")
1624
+ *
1625
+ * console.log(removeEmptyString(Option.none()))
1626
+ * // Output: { _id: 'Option', _tag: 'None' }
1627
+ *
1628
+ * console.log(removeEmptyString(Option.some("")))
1629
+ * // Output: { _id: 'Option', _tag: 'None' }
1630
+ *
1631
+ * console.log(removeEmptyString(Option.some("a")))
1632
+ * // Output: { _id: 'Option', _tag: 'Some', value: 'a' }
1633
+ * ```
1634
+ *
1635
+ * @category Filtering
1636
+ * @since 2.0.0
1637
+ */
1638
+ export const filter: {
1639
+ <A, B extends A>(refinement: Refinement<NoInfer<A>, B>): (self: Option<A>) => Option<B>
1640
+ <A>(predicate: Predicate<NoInfer<A>>): (self: Option<A>) => Option<A>
1641
+ <A, B extends A>(self: Option<A>, refinement: Refinement<A, B>): Option<B>
1642
+ <A>(self: Option<A>, predicate: Predicate<A>): Option<A>
1643
+ } = dual(
1644
+ 2,
1645
+ <A>(self: Option<A>, predicate: Predicate<A>): Option<A> =>
1646
+ filterMap(self, (b) => (predicate(b) ? option.some(b) : option.none))
1647
+ )
1648
+
1649
+ /**
1650
+ * Creates an `Equivalence` instance for comparing `Option` values, using a
1651
+ * provided `Equivalence` for the inner type.
1652
+ *
1653
+ * **Details**
1654
+ *
1655
+ * This function takes an `Equivalence` instance for a specific type `A` and
1656
+ * produces an `Equivalence` instance for `Option<A>`. The resulting
1657
+ * `Equivalence` determines whether two `Option` values are equivalent:
1658
+ *
1659
+ * - Two `None`s are considered equivalent.
1660
+ * - A `Some` and a `None` are not equivalent.
1661
+ * - Two `Some` values are equivalent if their inner values are equivalent
1662
+ * according to the provided `Equivalence`.
1663
+ *
1664
+ * **Example** (Comparing Optional Numbers for Equivalence)
1665
+ *
1666
+ * ```ts
1667
+ * import { Number, Option } from "effect"
1668
+ *
1669
+ * const isEquivalent = Option.getEquivalence(Number.Equivalence)
1670
+ *
1671
+ * console.log(isEquivalent(Option.none(), Option.none()))
1672
+ * // Output: true
1673
+ *
1674
+ * console.log(isEquivalent(Option.none(), Option.some(1)))
1675
+ * // Output: false
1676
+ *
1677
+ * console.log(isEquivalent(Option.some(1), Option.none()))
1678
+ * // Output: false
1679
+ *
1680
+ * console.log(isEquivalent(Option.some(1), Option.some(2)))
1681
+ * // Output: false
1682
+ *
1683
+ * console.log(isEquivalent(Option.some(1), Option.some(1)))
1684
+ * // Output: true
1685
+ * ```
1686
+ *
1687
+ * @category Equivalence
1688
+ * @since 2.0.0
1689
+ */
1690
+ export const getEquivalence = <A>(isEquivalent: Equivalence.Equivalence<A>): Equivalence.Equivalence<Option<A>> =>
1691
+ Equivalence.make((x, y) => isNone(x) ? isNone(y) : isNone(y) ? false : isEquivalent(x.value, y.value))
1692
+
1693
+ /**
1694
+ * Creates an `Order` instance for comparing `Option` values, using a provided
1695
+ * `Order` for the inner type.
1696
+ *
1697
+ * **Details**
1698
+ *
1699
+ * This function produces an `Order` instance for `Option<A>`, allowing `Option`
1700
+ * values to be compared:
1701
+ *
1702
+ * - `None` is always considered less than any `Some` value.
1703
+ * - If both are `Some`, their inner values are compared using the provided
1704
+ * `Order` instance.
1705
+ *
1706
+ * @example
1707
+ * ```ts
1708
+ * import { Number, Option } from "effect"
1709
+ *
1710
+ * const order = Option.getOrder(Number.Order)
1711
+ *
1712
+ * console.log(order(Option.none(), Option.none()))
1713
+ * // Output: 0
1714
+ *
1715
+ * console.log(order(Option.none(), Option.some(1)))
1716
+ * // Output: -1
1717
+ *
1718
+ * console.log(order(Option.some(1), Option.none()))
1719
+ * // Output: 1
1720
+ *
1721
+ * console.log(order(Option.some(1), Option.some(2)))
1722
+ * // Output: -1
1723
+ *
1724
+ * console.log(order(Option.some(1), Option.some(1)))
1725
+ * // Output: 0
1726
+ * ```
1727
+ *
1728
+ * @category Sorting
1729
+ * @since 2.0.0
1730
+ */
1731
+ export const getOrder = <A>(O: Order<A>): Order<Option<A>> =>
1732
+ order.make((self, that) => isSome(self) ? (isSome(that) ? O(self.value, that.value) : 1) : -1)
1733
+
1734
+ /**
1735
+ * Lifts a binary function to work with `Option` values, allowing the function
1736
+ * to operate on two `Option`s.
1737
+ *
1738
+ * **Details**
1739
+ *
1740
+ * This function takes a binary function `f` and returns a new function that
1741
+ * applies `f` to the values of two `Option`s (`self` and `that`). If both
1742
+ * `Option`s are `Some`, the binary function `f` is applied to their values, and
1743
+ * the result is wrapped in a new `Some`. If either `Option` is `None`, the
1744
+ * result is `None`.
1745
+ *
1746
+ * @example
1747
+ * ```ts
1748
+ * import { Option } from "effect"
1749
+ *
1750
+ * // A binary function to add two numbers
1751
+ * const add = (a: number, b: number): number => a + b
1752
+ *
1753
+ * // Lift the `add` function to work with `Option` values
1754
+ * const addOptions = Option.lift2(add)
1755
+ *
1756
+ * // Both `Option`s are `Some`
1757
+ * console.log(addOptions(Option.some(2), Option.some(3)))
1758
+ * // Output: { _id: 'Option', _tag: 'Some', value: 5 }
1759
+ *
1760
+ * // One `Option` is `None`
1761
+ * console.log(addOptions(Option.some(2), Option.none()))
1762
+ * // Output: { _id: 'Option', _tag: 'None' }
1763
+ * ```
1764
+ *
1765
+ * @category Lifting
1766
+ * @since 2.0.0
1767
+ */
1768
+ export const lift2 = <A, B, C>(f: (a: A, b: B) => C): {
1769
+ (that: Option<B>): (self: Option<A>) => Option<C>
1770
+ (self: Option<A>, that: Option<B>): Option<C>
1771
+ } => dual(2, (self: Option<A>, that: Option<B>): Option<C> => zipWith(self, that, f))
1772
+
1773
+ /**
1774
+ * Lifts a `Predicate` or `Refinement` into the `Option` context, returning a
1775
+ * `Some` of the input value if the predicate is satisfied, or `None` otherwise.
1776
+ *
1777
+ * **Details**
1778
+ *
1779
+ * This function transforms a `Predicate` (or a more specific `Refinement`) into
1780
+ * a function that produces an `Option`. If the predicate evaluates to `true`,
1781
+ * the input value is wrapped in a `Some`. If the predicate evaluates to
1782
+ * `false`, the result is `None`.
1783
+ *
1784
+ * @example
1785
+ * ```ts
1786
+ * import { Option } from "effect"
1787
+ *
1788
+ * // Check if a number is positive
1789
+ * const isPositive = (n: number) => n > 0
1790
+ *
1791
+ * // ┌─── (b: number) => Option<number>
1792
+ * // ▼
1793
+ * const parsePositive = Option.liftPredicate(isPositive)
1794
+ *
1795
+ * console.log(parsePositive(1))
1796
+ * // Output: { _id: 'Option', _tag: 'Some', value: 1 }
1797
+ *
1798
+ * console.log(parsePositive(-1))
1799
+ * // OUtput: { _id: 'Option', _tag: 'None' }
1800
+ * ```
1801
+ *
1802
+ * @category Lifting
1803
+ * @since 2.0.0
1804
+ */
1805
+ export const liftPredicate: { // Note: I intentionally avoid using the NoInfer pattern here.
1806
+ <A, B extends A>(refinement: Refinement<A, B>): (a: A) => Option<B>
1807
+ <B extends A, A = B>(predicate: Predicate<A>): (b: B) => Option<B>
1808
+ <A, B extends A>(
1809
+ self: A,
1810
+ refinement: Refinement<A, B>
1811
+ ): Option<B>
1812
+ <B extends A, A = B>(
1813
+ self: B,
1814
+ predicate: Predicate<A>
1815
+ ): Option<B>
1816
+ } = dual(
1817
+ 2,
1818
+ <B extends A, A = B>(b: B, predicate: Predicate<A>): Option<B> => predicate(b) ? some(b) : none()
1819
+ )
1820
+
1821
+ /**
1822
+ * Returns a function that checks if an `Option` contains a specified value,
1823
+ * using a provided equivalence function.
1824
+ *
1825
+ * **Details**
1826
+ *
1827
+ * This function allows you to check whether an `Option` contains a specific
1828
+ * value. It uses an equivalence function `isEquivalent` to compare the value
1829
+ * inside the `Option` to the provided value. If the `Option` is `Some` and the
1830
+ * equivalence function returns `true`, the result is `true`. If the `Option` is
1831
+ * `None` or the values are not equivalent, the result is `false`.
1832
+ *
1833
+ * @example
1834
+ * ```ts
1835
+ * import { Number, Option } from "effect"
1836
+ *
1837
+ * const contains = Option.containsWith(Number.Equivalence)
1838
+ *
1839
+ * console.log(Option.some(2).pipe(contains(2)))
1840
+ * // Output: true
1841
+ *
1842
+ * console.log(Option.some(1).pipe(contains(2)))
1843
+ * // Output: false
1844
+ *
1845
+ * console.log(Option.none().pipe(contains(2)))
1846
+ * // Output: false
1847
+ * ```
1848
+ *
1849
+ * @see {@link contains} for a version that uses the default `Equivalence`.
1850
+ *
1851
+ * @category Elements
1852
+ * @since 2.0.0
1853
+ */
1854
+ export const containsWith = <A>(isEquivalent: (self: A, that: A) => boolean): {
1855
+ (a: A): (self: Option<A>) => boolean
1856
+ (self: Option<A>, a: A): boolean
1857
+ } => dual(2, (self: Option<A>, a: A): boolean => isNone(self) ? false : isEquivalent(self.value, a))
1858
+
1859
+ const _equivalence = Equal.equivalence()
1860
+
1861
+ /**
1862
+ * Returns a function that checks if an `Option` contains a specified value
1863
+ * using the default `Equivalence`.
1864
+ *
1865
+ * **Details**
1866
+ *
1867
+ * This function allows you to check whether an `Option` contains a specific
1868
+ * value. It uses the default `Equivalence` for equality comparison. If the
1869
+ * `Option` is `Some` and its value is equivalent to the provided value, the
1870
+ * result is `true`. If the `Option` is `None` or the values are not equivalent,
1871
+ * the result is `false`.
1872
+ *
1873
+ * @example
1874
+ * ```ts
1875
+ * import { Option } from "effect"
1876
+ *
1877
+ * console.log(Option.some(2).pipe(Option.contains(2)))
1878
+ * // Output: true
1879
+ *
1880
+ * console.log(Option.some(1).pipe(Option.contains(2)))
1881
+ * // Output: false
1882
+ *
1883
+ * console.log(Option.none().pipe(Option.contains(2)))
1884
+ * // Output: false
1885
+ * ```
1886
+ *
1887
+ * @see {@link containsWith} for a version that allows you to specify a custom equivalence function.
1888
+ *
1889
+ * @category Elements
1890
+ * @since 2.0.0
1891
+ */
1892
+ export const contains: {
1893
+ <A>(a: A): (self: Option<A>) => boolean
1894
+ <A>(self: Option<A>, a: A): boolean
1895
+ } = containsWith(_equivalence)
1896
+
1897
+ /**
1898
+ * Checks if a value in an `Option` satisfies a given predicate or refinement.
1899
+ *
1900
+ * **Details**
1901
+ *
1902
+ * This function allows you to check if a value inside a `Some` meets a
1903
+ * specified condition. If the `Option` is `None`, the result is `false`. If the
1904
+ * `Option` is `Some`, the provided predicate or refinement is applied to the
1905
+ * value:
1906
+ *
1907
+ * - If the condition is met, the result is `true`.
1908
+ * - If the condition is not met, the result is `false`.
1909
+ *
1910
+ * @example
1911
+ * ```ts
1912
+ * import { Option } from "effect"
1913
+ *
1914
+ * const isEven = (n: number) => n % 2 === 0
1915
+ *
1916
+ * console.log(Option.some(2).pipe(Option.exists(isEven)))
1917
+ * // Output: true
1918
+ *
1919
+ * console.log(Option.some(1).pipe(Option.exists(isEven)))
1920
+ * // Output: false
1921
+ *
1922
+ * console.log(Option.none().pipe(Option.exists(isEven)))
1923
+ * // Output: false
1924
+ * ```
1925
+ *
1926
+ * @category Elements
1927
+ * @since 2.0.0
1928
+ */
1929
+ export const exists: {
1930
+ <A, B extends A>(refinement: Refinement<NoInfer<A>, B>): (self: Option<A>) => self is Option<B>
1931
+ <A>(predicate: Predicate<NoInfer<A>>): (self: Option<A>) => boolean
1932
+ <A, B extends A>(self: Option<A>, refinement: Refinement<A, B>): self is Option<B>
1933
+ <A>(self: Option<A>, predicate: Predicate<A>): boolean
1934
+ } = dual(
1935
+ 2,
1936
+ <A, B extends A>(self: Option<A>, refinement: Refinement<A, B>): self is Option<B> =>
1937
+ isNone(self) ? false : refinement(self.value)
1938
+ )
1939
+
1940
+ // -------------------------------------------------------------------------------------
1941
+ // do notation
1942
+ // -------------------------------------------------------------------------------------
1943
+
1944
+ /**
1945
+ * The "do simulation" in Effect allows you to write code in a more declarative style, similar to the "do notation" in other programming languages. It provides a way to define variables and perform operations on them using functions like `bind` and `let`.
1946
+ *
1947
+ * Here's how the do simulation works:
1948
+ *
1949
+ * 1. Start the do simulation using the `Do` value
1950
+ * 2. Within the do simulation scope, you can use the `bind` function to define variables and bind them to `Option` values
1951
+ * 3. You can accumulate multiple `bind` statements to define multiple variables within the scope
1952
+ * 4. Inside the do simulation scope, you can also use the `let` function to define variables and bind them to simple values
1953
+ * 5. Regular `Option` functions like `map` and `filter` can still be used within the do simulation. These functions will receive the accumulated variables as arguments within the scope
1954
+ *
1955
+ * @example
1956
+ * ```ts
1957
+ * import * as assert from "node:assert"
1958
+ * import { Option, pipe } from "effect"
1959
+ *
1960
+ * const result = pipe(
1961
+ * Option.Do,
1962
+ * Option.bind("x", () => Option.some(2)),
1963
+ * Option.bind("y", () => Option.some(3)),
1964
+ * Option.let("sum", ({ x, y }) => x + y),
1965
+ * Option.filter(({ x, y }) => x * y > 5)
1966
+ * )
1967
+ * assert.deepStrictEqual(result, Option.some({ x: 2, y: 3, sum: 5 }))
1968
+ * ```
1969
+ *
1970
+ * @see {@link Do}
1971
+ * @see {@link bind}
1972
+ * @see {@link let_ let}
1973
+ *
1974
+ * @category Do notation
1975
+ * @since 2.0.0
1976
+ */
1977
+ export const bindTo: {
1978
+ <N extends string>(name: N): <A>(self: Option<A>) => Option<{ [K in N]: A }>
1979
+ <A, N extends string>(self: Option<A>, name: N): Option<{ [K in N]: A }>
1980
+ } = doNotation.bindTo<OptionTypeLambda>(map)
1981
+
1982
+ const let_: {
1983
+ <N extends string, A extends object, B>(
1984
+ name: Exclude<N, keyof A>,
1985
+ f: (a: NoInfer<A>) => B
1986
+ ): (self: Option<A>) => Option<{ [K in N | keyof A]: K extends keyof A ? A[K] : B }>
1987
+ <A extends object, N extends string, B>(
1988
+ self: Option<A>,
1989
+ name: Exclude<N, keyof A>,
1990
+ f: (a: NoInfer<A>) => B
1991
+ ): Option<{ [K in N | keyof A]: K extends keyof A ? A[K] : B }>
1992
+ } = doNotation.let_<OptionTypeLambda>(map)
1993
+
1994
+ export {
1995
+ /**
1996
+ * The "do simulation" in Effect allows you to write code in a more declarative style, similar to the "do notation" in other programming languages. It provides a way to define variables and perform operations on them using functions like `bind` and `let`.
1997
+ *
1998
+ * Here's how the do simulation works:
1999
+ *
2000
+ * 1. Start the do simulation using the `Do` value
2001
+ * 2. Within the do simulation scope, you can use the `bind` function to define variables and bind them to `Option` values
2002
+ * 3. You can accumulate multiple `bind` statements to define multiple variables within the scope
2003
+ * 4. Inside the do simulation scope, you can also use the `let` function to define variables and bind them to simple values
2004
+ * 5. Regular `Option` functions like `map` and `filter` can still be used within the do simulation. These functions will receive the accumulated variables as arguments within the scope
2005
+ *
2006
+ * @example
2007
+ * ```ts
2008
+ * import * as assert from "node:assert"
2009
+ * import { Option, pipe } from "effect"
2010
+ *
2011
+ * const result = pipe(
2012
+ * Option.Do,
2013
+ * Option.bind("x", () => Option.some(2)),
2014
+ * Option.bind("y", () => Option.some(3)),
2015
+ * Option.let("sum", ({ x, y }) => x + y),
2016
+ * Option.filter(({ x, y }) => x * y > 5)
2017
+ * )
2018
+ * assert.deepStrictEqual(result, Option.some({ x: 2, y: 3, sum: 5 }))
2019
+ * ```
2020
+ *
2021
+ * @see {@link Do}
2022
+ * @see {@link bind}
2023
+ * @see {@link bindTo}
2024
+ *
2025
+ * @category Do notation
2026
+ * @since 2.0.0
2027
+ */
2028
+ let_ as let
2029
+ }
2030
+
2031
+ /**
2032
+ * The "do simulation" in Effect allows you to write code in a more declarative style, similar to the "do notation" in other programming languages. It provides a way to define variables and perform operations on them using functions like `bind` and `let`.
2033
+ *
2034
+ * Here's how the do simulation works:
2035
+ *
2036
+ * 1. Start the do simulation using the `Do` value
2037
+ * 2. Within the do simulation scope, you can use the `bind` function to define variables and bind them to `Option` values
2038
+ * 3. You can accumulate multiple `bind` statements to define multiple variables within the scope
2039
+ * 4. Inside the do simulation scope, you can also use the `let` function to define variables and bind them to simple values
2040
+ * 5. Regular `Option` functions like `map` and `filter` can still be used within the do simulation. These functions will receive the accumulated variables as arguments within the scope
2041
+ *
2042
+ * @example
2043
+ * ```ts
2044
+ * import * as assert from "node:assert"
2045
+ * import { Option, pipe } from "effect"
2046
+ *
2047
+ * const result = pipe(
2048
+ * Option.Do,
2049
+ * Option.bind("x", () => Option.some(2)),
2050
+ * Option.bind("y", () => Option.some(3)),
2051
+ * Option.let("sum", ({ x, y }) => x + y),
2052
+ * Option.filter(({ x, y }) => x * y > 5)
2053
+ * )
2054
+ * assert.deepStrictEqual(result, Option.some({ x: 2, y: 3, sum: 5 }))
2055
+ * ```
2056
+ *
2057
+ * @see {@link Do}
2058
+ * @see {@link bindTo}
2059
+ * @see {@link let_ let}
2060
+ *
2061
+ * @category Do notation
2062
+ * @since 2.0.0
2063
+ */
2064
+ export const bind: {
2065
+ <N extends string, A extends object, B>(
2066
+ name: Exclude<N, keyof A>,
2067
+ f: (a: NoInfer<A>) => Option<B>
2068
+ ): (self: Option<A>) => Option<{ [K in N | keyof A]: K extends keyof A ? A[K] : B }>
2069
+ <A extends object, N extends string, B>(
2070
+ self: Option<A>,
2071
+ name: Exclude<N, keyof A>,
2072
+ f: (a: NoInfer<A>) => Option<B>
2073
+ ): Option<{ [K in N | keyof A]: K extends keyof A ? A[K] : B }>
2074
+ } = doNotation.bind<OptionTypeLambda>(map, flatMap)
2075
+
2076
+ /**
2077
+ * The "do simulation" in Effect allows you to write code in a more declarative style, similar to the "do notation" in other programming languages. It provides a way to define variables and perform operations on them using functions like `bind` and `let`.
2078
+ *
2079
+ * Here's how the do simulation works:
2080
+ *
2081
+ * 1. Start the do simulation using the `Do` value
2082
+ * 2. Within the do simulation scope, you can use the `bind` function to define variables and bind them to `Option` values
2083
+ * 3. You can accumulate multiple `bind` statements to define multiple variables within the scope
2084
+ * 4. Inside the do simulation scope, you can also use the `let` function to define variables and bind them to simple values
2085
+ * 5. Regular `Option` functions like `map` and `filter` can still be used within the do simulation. These functions will receive the accumulated variables as arguments within the scope
2086
+ *
2087
+ * @example
2088
+ * ```ts
2089
+ * import * as assert from "node:assert"
2090
+ * import { Option, pipe } from "effect"
2091
+ *
2092
+ * const result = pipe(
2093
+ * Option.Do,
2094
+ * Option.bind("x", () => Option.some(2)),
2095
+ * Option.bind("y", () => Option.some(3)),
2096
+ * Option.let("sum", ({ x, y }) => x + y),
2097
+ * Option.filter(({ x, y }) => x * y > 5)
2098
+ * )
2099
+ * assert.deepStrictEqual(result, Option.some({ x: 2, y: 3, sum: 5 }))
2100
+ * ```
2101
+ *
2102
+ * @see {@link bindTo}
2103
+ * @see {@link bind}
2104
+ * @see {@link let_ let}
2105
+ *
2106
+ * @category Do notation
2107
+ * @since 2.0.0
2108
+ */
2109
+ export const Do: Option<{}> = some({})
2110
+
2111
+ const adapter = Gen.adapter<OptionTypeLambda>()
2112
+
2113
+ /**
2114
+ * Similar to `Effect.gen`, `Option.gen` provides a more readable,
2115
+ * generator-based syntax for working with `Option` values, making code that
2116
+ * involves `Option` easier to write and understand. This approach is similar to
2117
+ * using `async/await` but tailored for `Option`.
2118
+ *
2119
+ * **Example** (Using `Option.gen` to Create a Combined Value)
2120
+ *
2121
+ * ```ts
2122
+ * import { Option } from "effect"
2123
+ *
2124
+ * const maybeName: Option.Option<string> = Option.some("John")
2125
+ * const maybeAge: Option.Option<number> = Option.some(25)
2126
+ *
2127
+ * const person = Option.gen(function* () {
2128
+ * const name = (yield* maybeName).toUpperCase()
2129
+ * const age = yield* maybeAge
2130
+ * return { name, age }
2131
+ * })
2132
+ *
2133
+ * console.log(person)
2134
+ * // Output:
2135
+ * // { _id: 'Option', _tag: 'Some', value: { name: 'JOHN', age: 25 } }
2136
+ * ```
2137
+ *
2138
+ * @category Generators
2139
+ * @since 2.0.0
2140
+ */
2141
+ export const gen: Gen.Gen<OptionTypeLambda, Gen.Adapter<OptionTypeLambda>> = (...args) => {
2142
+ const f = args.length === 1 ? args[0] : args[1].bind(args[0])
2143
+ const iterator = f(adapter)
2144
+ let state: IteratorResult<any> = iterator.next()
2145
+ while (!state.done) {
2146
+ const current = Gen.isGenKind(state.value)
2147
+ ? state.value.value
2148
+ : Gen.yieldWrapGet(state.value)
2149
+ if (isNone(current)) {
2150
+ return current
2151
+ }
2152
+ state = iterator.next(current.value as never)
2153
+ }
2154
+ return some(state.value)
2155
+ }
2156
+
2157
+ /**
2158
+ * Merges two optional values, applying a function if both exist.
2159
+ * Unlike {@link zipWith}, this function returns `None` only if both inputs are `None`.
2160
+ *
2161
+ * @internal
2162
+ */
2163
+ export const mergeWith = <A>(f: (a1: A, a2: A) => A) => (o1: Option<A>, o2: Option<A>): Option<A> => {
2164
+ if (isNone(o1)) {
2165
+ return o2
2166
+ } else if (isNone(o2)) {
2167
+ return o1
2168
+ }
2169
+ return some(f(o1.value, o2.value))
2170
+ }