@clayroach/effect 3.19.14-source-capture.6 → 3.19.14-source-capture.8

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 (371) hide show
  1. package/dist/cjs/Utils.js +1 -1
  2. package/dist/cjs/Utils.js.map +1 -1
  3. package/dist/cjs/internal/clock.js +1 -1
  4. package/dist/cjs/internal/clock.js.map +1 -1
  5. package/dist/esm/Utils.js +1 -1
  6. package/dist/esm/Utils.js.map +1 -1
  7. package/dist/esm/internal/clock.js +1 -1
  8. package/dist/esm/internal/clock.js.map +1 -1
  9. package/package.json +1 -1
  10. package/src/Arbitrary.ts +0 -1101
  11. package/src/Array.ts +0 -3589
  12. package/src/BigDecimal.ts +0 -1349
  13. package/src/BigInt.ts +0 -643
  14. package/src/Boolean.ts +0 -287
  15. package/src/Brand.ts +0 -360
  16. package/src/Cache.ts +0 -281
  17. package/src/Cause.ts +0 -1555
  18. package/src/Channel.ts +0 -2355
  19. package/src/ChildExecutorDecision.ts +0 -146
  20. package/src/Chunk.ts +0 -1495
  21. package/src/Clock.ts +0 -111
  22. package/src/Config.ts +0 -542
  23. package/src/ConfigError.ts +0 -270
  24. package/src/ConfigProvider.ts +0 -333
  25. package/src/ConfigProviderPathPatch.ts +0 -100
  26. package/src/Console.ts +0 -226
  27. package/src/Context.ts +0 -585
  28. package/src/Cron.ts +0 -706
  29. package/src/Data.ts +0 -596
  30. package/src/DateTime.ts +0 -1686
  31. package/src/DefaultServices.ts +0 -34
  32. package/src/Deferred.ts +0 -301
  33. package/src/Differ.ts +0 -450
  34. package/src/Duration.ts +0 -1000
  35. package/src/Effect.ts +0 -14839
  36. package/src/Effectable.ts +0 -107
  37. package/src/Either.ts +0 -1040
  38. package/src/Encoding.ts +0 -195
  39. package/src/Equal.ts +0 -98
  40. package/src/Equivalence.ts +0 -235
  41. package/src/ExecutionPlan.ts +0 -308
  42. package/src/ExecutionStrategy.ts +0 -119
  43. package/src/Exit.ts +0 -467
  44. package/src/FastCheck.ts +0 -9
  45. package/src/Fiber.ts +0 -744
  46. package/src/FiberHandle.ts +0 -540
  47. package/src/FiberId.ts +0 -195
  48. package/src/FiberMap.ts +0 -656
  49. package/src/FiberRef.ts +0 -431
  50. package/src/FiberRefs.ts +0 -204
  51. package/src/FiberRefsPatch.ts +0 -105
  52. package/src/FiberSet.ts +0 -491
  53. package/src/FiberStatus.ts +0 -108
  54. package/src/Function.ts +0 -1222
  55. package/src/GlobalValue.ts +0 -53
  56. package/src/Graph.ts +0 -3732
  57. package/src/GroupBy.ts +0 -103
  58. package/src/HKT.ts +0 -45
  59. package/src/Hash.ts +0 -195
  60. package/src/HashMap.ts +0 -519
  61. package/src/HashRing.ts +0 -317
  62. package/src/HashSet.ts +0 -2346
  63. package/src/Inspectable.ts +0 -287
  64. package/src/Iterable.ts +0 -1119
  65. package/src/JSONSchema.ts +0 -1044
  66. package/src/KeyedPool.ts +0 -167
  67. package/src/Layer.ts +0 -1251
  68. package/src/LayerMap.ts +0 -436
  69. package/src/List.ts +0 -977
  70. package/src/LogLevel.ts +0 -285
  71. package/src/LogSpan.ts +0 -25
  72. package/src/Logger.ts +0 -702
  73. package/src/Mailbox.ts +0 -268
  74. package/src/ManagedRuntime.ts +0 -180
  75. package/src/Match.ts +0 -1477
  76. package/src/MergeDecision.ts +0 -95
  77. package/src/MergeState.ts +0 -172
  78. package/src/MergeStrategy.ts +0 -107
  79. package/src/Metric.ts +0 -780
  80. package/src/MetricBoundaries.ts +0 -69
  81. package/src/MetricHook.ts +0 -151
  82. package/src/MetricKey.ts +0 -224
  83. package/src/MetricKeyType.ts +0 -262
  84. package/src/MetricLabel.ts +0 -47
  85. package/src/MetricPair.ts +0 -71
  86. package/src/MetricPolling.ts +0 -148
  87. package/src/MetricRegistry.ts +0 -48
  88. package/src/MetricState.ts +0 -257
  89. package/src/Micro.ts +0 -4405
  90. package/src/ModuleVersion.ts +0 -18
  91. package/src/MutableHashMap.ts +0 -411
  92. package/src/MutableHashSet.ts +0 -706
  93. package/src/MutableList.ts +0 -297
  94. package/src/MutableQueue.ts +0 -227
  95. package/src/MutableRef.ts +0 -202
  96. package/src/NonEmptyIterable.ts +0 -32
  97. package/src/Number.ts +0 -1071
  98. package/src/Option.ts +0 -2170
  99. package/src/Order.ts +0 -373
  100. package/src/Ordering.ts +0 -111
  101. package/src/ParseResult.ts +0 -2031
  102. package/src/PartitionedSemaphore.ts +0 -200
  103. package/src/Pipeable.ts +0 -566
  104. package/src/Pool.ts +0 -204
  105. package/src/Predicate.ts +0 -1405
  106. package/src/Pretty.ts +0 -205
  107. package/src/PrimaryKey.ts +0 -23
  108. package/src/PubSub.ts +0 -182
  109. package/src/Queue.ts +0 -644
  110. package/src/Random.ts +0 -204
  111. package/src/RateLimiter.ts +0 -138
  112. package/src/RcMap.ts +0 -141
  113. package/src/RcRef.ts +0 -122
  114. package/src/Readable.ts +0 -93
  115. package/src/Record.ts +0 -1274
  116. package/src/RedBlackTree.ts +0 -421
  117. package/src/Redacted.ts +0 -144
  118. package/src/Ref.ts +0 -180
  119. package/src/RegExp.ts +0 -38
  120. package/src/Reloadable.ts +0 -127
  121. package/src/Request.ts +0 -347
  122. package/src/RequestBlock.ts +0 -118
  123. package/src/RequestResolver.ts +0 -366
  124. package/src/Resource.ts +0 -119
  125. package/src/Runtime.ts +0 -383
  126. package/src/RuntimeFlags.ts +0 -368
  127. package/src/RuntimeFlagsPatch.ts +0 -183
  128. package/src/STM.ts +0 -2045
  129. package/src/Schedule.ts +0 -2219
  130. package/src/ScheduleDecision.ts +0 -62
  131. package/src/ScheduleInterval.ts +0 -151
  132. package/src/ScheduleIntervals.ts +0 -122
  133. package/src/Scheduler.ts +0 -353
  134. package/src/Schema.ts +0 -10914
  135. package/src/SchemaAST.ts +0 -3043
  136. package/src/Scope.ts +0 -204
  137. package/src/ScopedCache.ts +0 -151
  138. package/src/ScopedRef.ts +0 -117
  139. package/src/Secret.ts +0 -88
  140. package/src/SingleProducerAsyncInput.ts +0 -67
  141. package/src/Sink.ts +0 -1461
  142. package/src/SortedMap.ts +0 -287
  143. package/src/SortedSet.ts +0 -390
  144. package/src/Stream.ts +0 -6468
  145. package/src/StreamEmit.ts +0 -136
  146. package/src/StreamHaltStrategy.ts +0 -123
  147. package/src/Streamable.ts +0 -45
  148. package/src/String.ts +0 -778
  149. package/src/Struct.ts +0 -243
  150. package/src/Subscribable.ts +0 -100
  151. package/src/SubscriptionRef.ts +0 -298
  152. package/src/Supervisor.ts +0 -240
  153. package/src/Symbol.ts +0 -29
  154. package/src/SynchronizedRef.ts +0 -270
  155. package/src/TArray.ts +0 -495
  156. package/src/TDeferred.ts +0 -100
  157. package/src/TMap.ts +0 -515
  158. package/src/TPriorityQueue.ts +0 -223
  159. package/src/TPubSub.ts +0 -200
  160. package/src/TQueue.ts +0 -432
  161. package/src/TRandom.ts +0 -129
  162. package/src/TReentrantLock.ts +0 -224
  163. package/src/TRef.ts +0 -178
  164. package/src/TSemaphore.ts +0 -129
  165. package/src/TSet.ts +0 -365
  166. package/src/TSubscriptionRef.ts +0 -192
  167. package/src/Take.ts +0 -258
  168. package/src/TestAnnotation.ts +0 -158
  169. package/src/TestAnnotationMap.ts +0 -119
  170. package/src/TestAnnotations.ts +0 -117
  171. package/src/TestClock.ts +0 -556
  172. package/src/TestConfig.ts +0 -47
  173. package/src/TestContext.ts +0 -36
  174. package/src/TestLive.ts +0 -53
  175. package/src/TestServices.ts +0 -390
  176. package/src/TestSized.ts +0 -55
  177. package/src/Tracer.ts +0 -198
  178. package/src/Trie.ts +0 -840
  179. package/src/Tuple.ts +0 -305
  180. package/src/Types.ts +0 -353
  181. package/src/Unify.ts +0 -113
  182. package/src/UpstreamPullRequest.ts +0 -117
  183. package/src/UpstreamPullStrategy.ts +0 -121
  184. package/src/Utils.ts +0 -809
  185. package/src/index.ts +0 -1561
  186. package/src/internal/array.ts +0 -8
  187. package/src/internal/blockedRequests.ts +0 -520
  188. package/src/internal/cache.ts +0 -733
  189. package/src/internal/cause.ts +0 -1050
  190. package/src/internal/channel/channelExecutor.ts +0 -1200
  191. package/src/internal/channel/channelState.ts +0 -134
  192. package/src/internal/channel/childExecutorDecision.ts +0 -96
  193. package/src/internal/channel/continuation.ts +0 -200
  194. package/src/internal/channel/mergeDecision.ts +0 -113
  195. package/src/internal/channel/mergeState.ts +0 -120
  196. package/src/internal/channel/mergeStrategy.ts +0 -72
  197. package/src/internal/channel/singleProducerAsyncInput.ts +0 -259
  198. package/src/internal/channel/subexecutor.ts +0 -229
  199. package/src/internal/channel/upstreamPullRequest.ts +0 -84
  200. package/src/internal/channel/upstreamPullStrategy.ts +0 -87
  201. package/src/internal/channel.ts +0 -2603
  202. package/src/internal/clock.ts +0 -95
  203. package/src/internal/completedRequestMap.ts +0 -9
  204. package/src/internal/concurrency.ts +0 -54
  205. package/src/internal/config.ts +0 -716
  206. package/src/internal/configError.ts +0 -304
  207. package/src/internal/configProvider/pathPatch.ts +0 -97
  208. package/src/internal/configProvider.ts +0 -799
  209. package/src/internal/console.ts +0 -153
  210. package/src/internal/context.ts +0 -337
  211. package/src/internal/core-effect.ts +0 -2293
  212. package/src/internal/core-stream.ts +0 -998
  213. package/src/internal/core.ts +0 -3273
  214. package/src/internal/data.ts +0 -36
  215. package/src/internal/dataSource.ts +0 -327
  216. package/src/internal/dateTime.ts +0 -1277
  217. package/src/internal/defaultServices/console.ts +0 -100
  218. package/src/internal/defaultServices.ts +0 -163
  219. package/src/internal/deferred.ts +0 -46
  220. package/src/internal/differ/chunkPatch.ts +0 -211
  221. package/src/internal/differ/contextPatch.ts +0 -232
  222. package/src/internal/differ/hashMapPatch.ts +0 -220
  223. package/src/internal/differ/hashSetPatch.ts +0 -176
  224. package/src/internal/differ/orPatch.ts +0 -311
  225. package/src/internal/differ/readonlyArrayPatch.ts +0 -210
  226. package/src/internal/differ.ts +0 -200
  227. package/src/internal/doNotation.ts +0 -80
  228. package/src/internal/effect/circular.ts +0 -905
  229. package/src/internal/effectable.ts +0 -131
  230. package/src/internal/either.ts +0 -110
  231. package/src/internal/encoding/base64.ts +0 -286
  232. package/src/internal/encoding/base64Url.ts +0 -29
  233. package/src/internal/encoding/common.ts +0 -51
  234. package/src/internal/encoding/hex.ts +0 -315
  235. package/src/internal/errors.ts +0 -7
  236. package/src/internal/executionPlan.ts +0 -114
  237. package/src/internal/executionStrategy.ts +0 -74
  238. package/src/internal/fiber.ts +0 -388
  239. package/src/internal/fiberId.ts +0 -267
  240. package/src/internal/fiberMessage.ts +0 -82
  241. package/src/internal/fiberRefs/patch.ts +0 -144
  242. package/src/internal/fiberRefs.ts +0 -297
  243. package/src/internal/fiberRuntime.ts +0 -3915
  244. package/src/internal/fiberScope.ts +0 -71
  245. package/src/internal/fiberStatus.ts +0 -119
  246. package/src/internal/groupBy.ts +0 -530
  247. package/src/internal/hashMap/array.ts +0 -49
  248. package/src/internal/hashMap/bitwise.ts +0 -32
  249. package/src/internal/hashMap/config.ts +0 -14
  250. package/src/internal/hashMap/keySet.ts +0 -8
  251. package/src/internal/hashMap/node.ts +0 -391
  252. package/src/internal/hashMap.ts +0 -586
  253. package/src/internal/hashSet.ts +0 -323
  254. package/src/internal/keyedPool.ts +0 -244
  255. package/src/internal/layer/circular.ts +0 -228
  256. package/src/internal/layer.ts +0 -1487
  257. package/src/internal/logSpan.ts +0 -20
  258. package/src/internal/logger-circular.ts +0 -24
  259. package/src/internal/logger.ts +0 -485
  260. package/src/internal/mailbox.ts +0 -561
  261. package/src/internal/managedRuntime/circular.ts +0 -6
  262. package/src/internal/managedRuntime.ts +0 -134
  263. package/src/internal/matcher.ts +0 -652
  264. package/src/internal/metric/boundaries.ts +0 -75
  265. package/src/internal/metric/hook.ts +0 -483
  266. package/src/internal/metric/key.ts +0 -167
  267. package/src/internal/metric/keyType.ts +0 -238
  268. package/src/internal/metric/label.ts +0 -41
  269. package/src/internal/metric/pair.ts +0 -48
  270. package/src/internal/metric/polling.ts +0 -149
  271. package/src/internal/metric/registry.ts +0 -187
  272. package/src/internal/metric/state.ts +0 -290
  273. package/src/internal/metric.ts +0 -577
  274. package/src/internal/opCodes/cause.ts +0 -35
  275. package/src/internal/opCodes/channel.ts +0 -83
  276. package/src/internal/opCodes/channelChildExecutorDecision.ts +0 -17
  277. package/src/internal/opCodes/channelMergeDecision.ts +0 -11
  278. package/src/internal/opCodes/channelMergeState.ts +0 -17
  279. package/src/internal/opCodes/channelMergeStrategy.ts +0 -11
  280. package/src/internal/opCodes/channelState.ts +0 -23
  281. package/src/internal/opCodes/channelUpstreamPullRequest.ts +0 -11
  282. package/src/internal/opCodes/channelUpstreamPullStrategy.ts +0 -11
  283. package/src/internal/opCodes/config.ts +0 -65
  284. package/src/internal/opCodes/configError.ts +0 -35
  285. package/src/internal/opCodes/continuation.ts +0 -11
  286. package/src/internal/opCodes/deferred.ts +0 -11
  287. package/src/internal/opCodes/effect.ts +0 -89
  288. package/src/internal/opCodes/layer.ts +0 -59
  289. package/src/internal/opCodes/streamHaltStrategy.ts +0 -23
  290. package/src/internal/option.ts +0 -80
  291. package/src/internal/pool.ts +0 -432
  292. package/src/internal/pubsub.ts +0 -1762
  293. package/src/internal/query.ts +0 -204
  294. package/src/internal/queue.ts +0 -766
  295. package/src/internal/random.ts +0 -161
  296. package/src/internal/rateLimiter.ts +0 -93
  297. package/src/internal/rcMap.ts +0 -285
  298. package/src/internal/rcRef.ts +0 -192
  299. package/src/internal/redBlackTree/iterator.ts +0 -200
  300. package/src/internal/redBlackTree/node.ts +0 -68
  301. package/src/internal/redBlackTree.ts +0 -1245
  302. package/src/internal/redacted.ts +0 -73
  303. package/src/internal/ref.ts +0 -171
  304. package/src/internal/reloadable.ts +0 -140
  305. package/src/internal/request.ts +0 -177
  306. package/src/internal/resource.ts +0 -76
  307. package/src/internal/ringBuffer.ts +0 -68
  308. package/src/internal/runtime.ts +0 -558
  309. package/src/internal/runtimeFlags.ts +0 -188
  310. package/src/internal/runtimeFlagsPatch.ts +0 -103
  311. package/src/internal/schedule/decision.ts +0 -47
  312. package/src/internal/schedule/interval.ts +0 -101
  313. package/src/internal/schedule/intervals.ts +0 -180
  314. package/src/internal/schedule.ts +0 -2199
  315. package/src/internal/schema/errors.ts +0 -191
  316. package/src/internal/schema/schemaId.ts +0 -106
  317. package/src/internal/schema/util.ts +0 -50
  318. package/src/internal/scopedCache.ts +0 -644
  319. package/src/internal/scopedRef.ts +0 -118
  320. package/src/internal/secret.ts +0 -89
  321. package/src/internal/singleShotGen.ts +0 -35
  322. package/src/internal/sink.ts +0 -2120
  323. package/src/internal/stack.ts +0 -10
  324. package/src/internal/stm/core.ts +0 -817
  325. package/src/internal/stm/entry.ts +0 -59
  326. package/src/internal/stm/journal.ts +0 -123
  327. package/src/internal/stm/opCodes/stm.ts +0 -71
  328. package/src/internal/stm/opCodes/stmState.ts +0 -17
  329. package/src/internal/stm/opCodes/strategy.ts +0 -17
  330. package/src/internal/stm/opCodes/tExit.ts +0 -29
  331. package/src/internal/stm/opCodes/tryCommit.ts +0 -11
  332. package/src/internal/stm/stm.ts +0 -1453
  333. package/src/internal/stm/stmState.ts +0 -136
  334. package/src/internal/stm/tArray.ts +0 -550
  335. package/src/internal/stm/tDeferred.ts +0 -81
  336. package/src/internal/stm/tExit.ts +0 -190
  337. package/src/internal/stm/tMap.ts +0 -824
  338. package/src/internal/stm/tPriorityQueue.ts +0 -267
  339. package/src/internal/stm/tPubSub.ts +0 -551
  340. package/src/internal/stm/tQueue.ts +0 -393
  341. package/src/internal/stm/tRandom.ts +0 -140
  342. package/src/internal/stm/tReentrantLock.ts +0 -352
  343. package/src/internal/stm/tRef.ts +0 -195
  344. package/src/internal/stm/tSemaphore.ts +0 -113
  345. package/src/internal/stm/tSet.ts +0 -259
  346. package/src/internal/stm/tSubscriptionRef.ts +0 -286
  347. package/src/internal/stm/tryCommit.ts +0 -34
  348. package/src/internal/stm/txnId.ts +0 -14
  349. package/src/internal/stm/versioned.ts +0 -4
  350. package/src/internal/stream/debounceState.ts +0 -57
  351. package/src/internal/stream/emit.ts +0 -123
  352. package/src/internal/stream/haltStrategy.ts +0 -94
  353. package/src/internal/stream/handoff.ts +0 -187
  354. package/src/internal/stream/handoffSignal.ts +0 -59
  355. package/src/internal/stream/pull.ts +0 -34
  356. package/src/internal/stream/sinkEndReason.ts +0 -30
  357. package/src/internal/stream/zipAllState.ts +0 -88
  358. package/src/internal/stream/zipChunksState.ts +0 -56
  359. package/src/internal/stream.ts +0 -8801
  360. package/src/internal/string-utils.ts +0 -107
  361. package/src/internal/subscriptionRef.ts +0 -138
  362. package/src/internal/supervisor/patch.ts +0 -190
  363. package/src/internal/supervisor.ts +0 -303
  364. package/src/internal/synchronizedRef.ts +0 -114
  365. package/src/internal/take.ts +0 -199
  366. package/src/internal/testing/sleep.ts +0 -27
  367. package/src/internal/testing/suspendedWarningData.ts +0 -85
  368. package/src/internal/testing/warningData.ts +0 -94
  369. package/src/internal/tracer.ts +0 -293
  370. package/src/internal/trie.ts +0 -722
  371. package/src/internal/version.ts +0 -7
package/src/Option.ts DELETED
@@ -1,2170 +0,0 @@
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
- }