effect 3.12.7 → 3.12.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 (117) hide show
  1. package/dist/cjs/BigDecimal.js +1 -1
  2. package/dist/cjs/BigDecimal.js.map +1 -1
  3. package/dist/cjs/Cause.js +630 -167
  4. package/dist/cjs/Cause.js.map +1 -1
  5. package/dist/cjs/Chunk.js +4 -8
  6. package/dist/cjs/Chunk.js.map +1 -1
  7. package/dist/cjs/ConfigProvider.js +1 -0
  8. package/dist/cjs/ConfigProvider.js.map +1 -1
  9. package/dist/cjs/Cron.js +26 -10
  10. package/dist/cjs/Cron.js.map +1 -1
  11. package/dist/cjs/Duration.js +7 -4
  12. package/dist/cjs/Duration.js.map +1 -1
  13. package/dist/cjs/Effect.js.map +1 -1
  14. package/dist/cjs/Either.js +5 -24
  15. package/dist/cjs/Either.js.map +1 -1
  16. package/dist/cjs/Layer.js.map +1 -1
  17. package/dist/cjs/Option.js +1042 -363
  18. package/dist/cjs/Option.js.map +1 -1
  19. package/dist/cjs/ParseResult.js +41 -18
  20. package/dist/cjs/ParseResult.js.map +1 -1
  21. package/dist/cjs/Schedule.js +8 -1
  22. package/dist/cjs/Schedule.js.map +1 -1
  23. package/dist/cjs/Schema.js +51 -10
  24. package/dist/cjs/Schema.js.map +1 -1
  25. package/dist/cjs/internal/cause.js +23 -108
  26. package/dist/cjs/internal/cause.js.map +1 -1
  27. package/dist/cjs/internal/core.js +4 -5
  28. package/dist/cjs/internal/core.js.map +1 -1
  29. package/dist/cjs/internal/layer.js.map +1 -1
  30. package/dist/cjs/internal/schedule.js.map +1 -1
  31. package/dist/cjs/internal/secret.js +6 -5
  32. package/dist/cjs/internal/secret.js.map +1 -1
  33. package/dist/cjs/internal/stream.js +21 -23
  34. package/dist/cjs/internal/stream.js.map +1 -1
  35. package/dist/cjs/internal/version.js +1 -1
  36. package/dist/dts/BigDecimal.d.ts.map +1 -1
  37. package/dist/dts/Cause.d.ts +1157 -304
  38. package/dist/dts/Cause.d.ts.map +1 -1
  39. package/dist/dts/Chunk.d.ts +3 -6
  40. package/dist/dts/Chunk.d.ts.map +1 -1
  41. package/dist/dts/ConfigProvider.d.ts.map +1 -1
  42. package/dist/dts/Cron.d.ts +25 -9
  43. package/dist/dts/Cron.d.ts.map +1 -1
  44. package/dist/dts/Duration.d.ts +1 -1
  45. package/dist/dts/Duration.d.ts.map +1 -1
  46. package/dist/dts/Effect.d.ts +3 -2
  47. package/dist/dts/Effect.d.ts.map +1 -1
  48. package/dist/dts/Either.d.ts.map +1 -1
  49. package/dist/dts/Layer.d.ts +1 -1
  50. package/dist/dts/Layer.d.ts.map +1 -1
  51. package/dist/dts/Option.d.ts +2288 -784
  52. package/dist/dts/Option.d.ts.map +1 -1
  53. package/dist/dts/ParseResult.d.ts +4 -4
  54. package/dist/dts/ParseResult.d.ts.map +1 -1
  55. package/dist/dts/Schedule.d.ts +7 -0
  56. package/dist/dts/Schedule.d.ts.map +1 -1
  57. package/dist/dts/Schema.d.ts +15 -4
  58. package/dist/dts/Schema.d.ts.map +1 -1
  59. package/dist/dts/internal/core.d.ts.map +1 -1
  60. package/dist/dts/internal/stream.d.ts +1 -1
  61. package/dist/dts/internal/stream.d.ts.map +1 -1
  62. package/dist/esm/BigDecimal.js +1 -1
  63. package/dist/esm/BigDecimal.js.map +1 -1
  64. package/dist/esm/Cause.js +630 -167
  65. package/dist/esm/Cause.js.map +1 -1
  66. package/dist/esm/Chunk.js +4 -8
  67. package/dist/esm/Chunk.js.map +1 -1
  68. package/dist/esm/ConfigProvider.js +1 -0
  69. package/dist/esm/ConfigProvider.js.map +1 -1
  70. package/dist/esm/Cron.js +27 -11
  71. package/dist/esm/Cron.js.map +1 -1
  72. package/dist/esm/Duration.js +7 -4
  73. package/dist/esm/Duration.js.map +1 -1
  74. package/dist/esm/Effect.js.map +1 -1
  75. package/dist/esm/Either.js +5 -24
  76. package/dist/esm/Either.js.map +1 -1
  77. package/dist/esm/Layer.js.map +1 -1
  78. package/dist/esm/Option.js +1041 -363
  79. package/dist/esm/Option.js.map +1 -1
  80. package/dist/esm/ParseResult.js +41 -18
  81. package/dist/esm/ParseResult.js.map +1 -1
  82. package/dist/esm/Schedule.js +7 -0
  83. package/dist/esm/Schedule.js.map +1 -1
  84. package/dist/esm/Schema.js +51 -10
  85. package/dist/esm/Schema.js.map +1 -1
  86. package/dist/esm/internal/cause.js +22 -108
  87. package/dist/esm/internal/cause.js.map +1 -1
  88. package/dist/esm/internal/core.js +4 -5
  89. package/dist/esm/internal/core.js.map +1 -1
  90. package/dist/esm/internal/layer.js.map +1 -1
  91. package/dist/esm/internal/schedule.js.map +1 -1
  92. package/dist/esm/internal/secret.js +5 -4
  93. package/dist/esm/internal/secret.js.map +1 -1
  94. package/dist/esm/internal/stream.js +21 -23
  95. package/dist/esm/internal/stream.js.map +1 -1
  96. package/dist/esm/internal/version.js +1 -1
  97. package/package.json +1 -1
  98. package/src/BigDecimal.ts +1 -1
  99. package/src/Cause.ts +1158 -304
  100. package/src/Chunk.ts +8 -11
  101. package/src/ConfigProvider.ts +1 -0
  102. package/src/Cron.ts +28 -11
  103. package/src/Duration.ts +10 -5
  104. package/src/Effect.ts +5 -2
  105. package/src/Either.ts +11 -28
  106. package/src/Layer.ts +1 -1
  107. package/src/Option.ts +2314 -820
  108. package/src/ParseResult.ts +53 -29
  109. package/src/Schedule.ts +8 -0
  110. package/src/Schema.ts +68 -12
  111. package/src/internal/cause.ts +38 -137
  112. package/src/internal/core.ts +4 -5
  113. package/src/internal/layer.ts +1 -1
  114. package/src/internal/schedule.ts +7 -6
  115. package/src/internal/secret.ts +6 -4
  116. package/src/internal/stream.ts +24 -37
  117. package/src/internal/version.ts +1 -1
@@ -7,102 +7,167 @@ import * as option from "./internal/option.js";
7
7
  import * as order from "./Order.js";
8
8
  import * as Gen from "./Utils.js";
9
9
  /**
10
- * @category symbols
10
+ * @category Symbols
11
11
  * @since 2.0.0
12
12
  */
13
13
  export const TypeId = /*#__PURE__*/Symbol.for("effect/Option");
14
14
  /**
15
- * Creates a new `Option` that represents the absence of a value.
15
+ * Represents the absence of a value by creating an empty `Option`.
16
16
  *
17
- * @category constructors
17
+ * `Option.none` returns an `Option<never>`, which is a subtype of `Option<A>`.
18
+ * This means you can use it in place of any `Option<A>` regardless of the type
19
+ * `A`.
20
+ *
21
+ * @see {@link some} for the opposite operation.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * // Title: Creating an Option with No Value
26
+ * import { Option } from "effect"
27
+ *
28
+ * // An Option holding no value
29
+ * //
30
+ * // ┌─── Option<never>
31
+ * // ▼
32
+ * const noValue = Option.none()
33
+ *
34
+ * console.log(noValue)
35
+ * // Output: { _id: 'Option', _tag: 'None' }
36
+ * ```
37
+ *
38
+ * @category Constructors
18
39
  * @since 2.0.0
19
40
  */
20
41
  export const none = () => option.none;
21
42
  /**
22
- * Creates a new `Option` that wraps the given value.
43
+ * Wraps the given value into an `Option` to represent its presence.
23
44
  *
24
- * @param value - The value to wrap.
45
+ * @see {@link none} for the opposite operation.
25
46
  *
26
- * @category constructors
47
+ * @example
48
+ * ```ts
49
+ * // Title: Creating an Option with a Value
50
+ * import { Option } from "effect"
51
+ *
52
+ * // An Option holding the number 1
53
+ * //
54
+ * // ┌─── Option<number>
55
+ * // ▼
56
+ * const value = Option.some(1)
57
+ *
58
+ * console.log(value)
59
+ * // Output: { _id: 'Option', _tag: 'Some', value: 1 }
60
+ * ```
61
+ *
62
+ * @category Constructors
27
63
  * @since 2.0.0
28
64
  */
29
65
  export const some = option.some;
30
66
  /**
31
- * Checks if a given value is an `Option` value.
67
+ * Determines whether the given value is an `Option`.
32
68
  *
33
- * @param input - The value to check.
69
+ * **Details**
70
+ *
71
+ * This function checks if a value is an instance of `Option`. It returns `true`
72
+ * if the value is either `Option.some` or `Option.none`, and `false` otherwise.
73
+ * This is particularly useful when working with unknown values or when you need
74
+ * to ensure type safety in your code.
34
75
  *
35
76
  * @example
36
77
  * ```ts
37
78
  * import { Option } from "effect"
38
79
  *
39
- * assert.deepStrictEqual(Option.isOption(Option.some(1)), true)
40
- * assert.deepStrictEqual(Option.isOption(Option.none()), true)
41
- * assert.deepStrictEqual(Option.isOption({}), false)
80
+ * console.log(Option.isOption(Option.some(1)))
81
+ * // Output: true
82
+ *
83
+ * console.log(Option.isOption(Option.none()))
84
+ * // Output: true
85
+ *
86
+ * console.log(Option.isOption({}))
87
+ * // Output: false
42
88
  * ```
43
89
  *
44
- * @category guards
90
+ * @category Guards
45
91
  * @since 2.0.0
46
92
  */
47
93
  export const isOption = option.isOption;
48
94
  /**
49
- * Determine if a `Option` is a `None`.
95
+ * Checks whether an `Option` represents the absence of a value (`None`).
50
96
  *
51
- * @param self - The `Option` to check.
97
+ * @see {@link isSome} for the opposite check.
52
98
  *
53
99
  * @example
54
100
  * ```ts
55
101
  * import { Option } from "effect"
56
102
  *
57
- * assert.deepStrictEqual(Option.isNone(Option.some(1)), false)
58
- * assert.deepStrictEqual(Option.isNone(Option.none()), true)
103
+ * console.log(Option.isNone(Option.some(1)))
104
+ * // Output: false
105
+ *
106
+ * console.log(Option.isNone(Option.none()))
107
+ * // Output: true
59
108
  * ```
60
109
  *
61
- * @category guards
110
+ * @category Guards
62
111
  * @since 2.0.0
63
112
  */
64
113
  export const isNone = option.isNone;
65
114
  /**
66
- * Determine if a `Option` is a `Some`.
115
+ * Checks whether an `Option` contains a value (`Some`).
67
116
  *
68
- * @param self - The `Option` to check.
117
+ * @see {@link isNone} for the opposite check.
69
118
  *
70
119
  * @example
71
120
  * ```ts
72
121
  * import { Option } from "effect"
73
122
  *
74
- * assert.deepStrictEqual(Option.isSome(Option.some(1)), true)
75
- * assert.deepStrictEqual(Option.isSome(Option.none()), false)
123
+ * console.log(Option.isSome(Option.some(1)))
124
+ * // Output: true
125
+ *
126
+ * console.log(Option.isSome(Option.none()))
127
+ * // Output: false
76
128
  * ```
77
129
  *
78
- * @category guards
130
+ * @category Guards
79
131
  * @since 2.0.0
80
132
  */
81
133
  export const isSome = option.isSome;
82
134
  /**
83
- * Matches the given `Option` and returns either the provided `onNone` value or the result of the provided `onSome`
84
- * function when passed the `Option`'s value.
135
+ * Performs pattern matching on an `Option` to handle both `Some` and `None`
136
+ * cases.
137
+ *
138
+ * **Details**
139
+ *
140
+ * This function allows you to match against an `Option` and handle both
141
+ * scenarios: when the `Option` is `None` (i.e., contains no value), and when
142
+ * the `Option` is `Some` (i.e., contains a value). It executes one of the
143
+ * provided functions based on the case:
85
144
  *
86
- * @param self - The `Option` to match
87
- * @param onNone - The value to be returned if the `Option` is `None`
88
- * @param onSome - The function to be called if the `Option` is `Some`, it will be passed the `Option`'s value and its result will be returned
145
+ * - If the `Option` is `None`, the `onNone` function is executed and its result
146
+ * is returned.
147
+ * - If the `Option` is `Some`, the `onSome` function is executed with the
148
+ * contained value, and its result is returned.
149
+ *
150
+ * This function provides a concise and functional way to handle optional values
151
+ * without resorting to `if` or manual checks, making your code more declarative
152
+ * and readable.
89
153
  *
90
154
  * @example
91
155
  * ```ts
92
- * import { pipe, Option } from "effect"
156
+ * // Title: Pattern Matching with Option
157
+ * import { Option } from "effect"
93
158
  *
94
- * assert.deepStrictEqual(
95
- * pipe(Option.some(1), Option.match({ onNone: () => 'a none', onSome: (a) => `a some containing ${a}` })),
96
- * 'a some containing 1'
97
- * )
159
+ * const foo = Option.some(1)
98
160
  *
99
- * assert.deepStrictEqual(
100
- * pipe(Option.none(), Option.match({ onNone: () => 'a none', onSome: (a) => `a some containing ${a}` })),
101
- * 'a none'
102
- * )
161
+ * const message = Option.match(foo, {
162
+ * onNone: () => "Option is empty",
163
+ * onSome: (value) => `Option has a value: ${value}`
164
+ * })
165
+ *
166
+ * console.log(message)
167
+ * // Output: "Option has a value: 1"
103
168
  * ```
104
169
  *
105
- * @category pattern matching
170
+ * @category Pattern matching
106
171
  * @since 2.0.0
107
172
  */
108
173
  export const match = /*#__PURE__*/dual(2, (self, {
@@ -110,41 +175,76 @@ export const match = /*#__PURE__*/dual(2, (self, {
110
175
  onSome
111
176
  }) => isNone(self) ? onNone() : onSome(self.value));
112
177
  /**
113
- * Returns a type guard from a `Option` returning function.
114
- * This function ensures that a type guard definition is type-safe.
178
+ * Converts an `Option`-returning function into a type guard.
179
+ *
180
+ * **Details**
181
+ *
182
+ * This function transforms a function that returns an `Option` into a type
183
+ * guard, ensuring type safety when validating or narrowing types. The returned
184
+ * type guard function checks whether the input satisfies the condition defined
185
+ * in the original `Option`-returning function.
186
+ *
187
+ * If the original function returns `Option.some`, the type guard evaluates to
188
+ * `true`, confirming the input is of the desired type. If the function returns
189
+ * `Option.none`, the type guard evaluates to `false`.
190
+ *
191
+ * This utility is especially useful for validating types in union types,
192
+ * filtering arrays, or ensuring safe handling of specific subtypes.
115
193
  *
116
194
  * @example
117
195
  * ```ts
118
196
  * import { Option } from "effect"
119
197
  *
120
- * const parsePositive = (n: number): Option.Option<number> =>
121
- * n > 0 ? Option.some(n) : Option.none()
198
+ * type MyData = string | number
199
+ *
200
+ * const parseString = (data: MyData): Option.Option<string> =>
201
+ * typeof data === "string" ? Option.some(data) : Option.none()
122
202
  *
123
- * const isPositive = Option.toRefinement(parsePositive)
203
+ * // ┌─── (a: MyData) => a is string
204
+ * // ▼
205
+ * const isString = Option.toRefinement(parseString)
124
206
  *
125
- * assert.deepStrictEqual(isPositive(1), true)
126
- * assert.deepStrictEqual(isPositive(-1), false)
207
+ * console.log(isString("a"))
208
+ * // Output: true
209
+ *
210
+ * console.log(isString(1))
211
+ * // Output: false
127
212
  * ```
128
213
  *
129
- * @category conversions
214
+ * @category Conversions
130
215
  * @since 2.0.0
131
216
  */
132
217
  export const toRefinement = f => a => isSome(f(a));
133
218
  /**
134
- * Converts an `Iterable` of values into an `Option`. Returns the first value of the `Iterable` wrapped in a `Some`
135
- * if the `Iterable` is not empty, otherwise returns `None`.
219
+ * Converts an `Iterable` into an `Option`, wrapping the first element if it
220
+ * exists.
221
+ *
222
+ * **Details**
223
+ *
224
+ * This function takes an `Iterable` (e.g., an array, a generator, or any object
225
+ * implementing the `Iterable` interface) and returns an `Option` based on its
226
+ * content:
136
227
  *
137
- * @param collection - The `Iterable` to be converted to an `Option`.
228
+ * - If the `Iterable` contains at least one element, the first element is
229
+ * wrapped in a `Some` and returned.
230
+ * - If the `Iterable` is empty, `None` is returned, representing the absence of
231
+ * a value.
232
+ *
233
+ * This utility is useful for safely handling collections that might be empty,
234
+ * ensuring you explicitly handle both cases where a value exists or doesn't.
138
235
  *
139
236
  * @example
140
237
  * ```ts
141
238
  * import { Option } from "effect"
142
239
  *
143
- * assert.deepStrictEqual(Option.fromIterable([1, 2, 3]), Option.some(1))
144
- * assert.deepStrictEqual(Option.fromIterable([]), Option.none())
240
+ * console.log(Option.fromIterable([1, 2, 3]))
241
+ * // Output: { _id: 'Option', _tag: 'Some', value: 1 }
242
+ *
243
+ * console.log(Option.fromIterable([]))
244
+ * // Output: { _id: 'Option', _tag: 'None' }
145
245
  * ```
146
246
  *
147
- * @category constructors
247
+ * @category Constructors
148
248
  * @since 2.0.0
149
249
  */
150
250
  export const fromIterable = collection => {
@@ -154,153 +254,226 @@ export const fromIterable = collection => {
154
254
  return none();
155
255
  };
156
256
  /**
157
- * Converts a `Either` to an `Option` discarding the error.
257
+ * Converts an `Either` into an `Option` by discarding the error and extracting
258
+ * the right value.
259
+ *
260
+ * **Details**
261
+ *
262
+ * This function takes an `Either` and returns an `Option` based on its value:
263
+ *
264
+ * - If the `Either` is a `Right`, its value is wrapped in a `Some` and
265
+ * returned.
266
+ * - If the `Either` is a `Left`, the error is discarded, and `None` is
267
+ * returned.
268
+ *
269
+ * This is particularly useful when you only care about the success case
270
+ * (`Right`) of an `Either` and want to handle the result using `Option`. By
271
+ * using this function, you can convert `Either` into a simpler structure for
272
+ * cases where error handling is not required.
273
+ *
274
+ * @see {@link getLeft} for the opposite operation.
158
275
  *
159
276
  * @example
160
277
  * ```ts
161
- * import { Option, Either } from "effect"
278
+ * import { Either, Option } from "effect"
279
+ *
280
+ * console.log(Option.getRight(Either.right("ok")))
281
+ * // Output: { _id: 'Option', _tag: 'Some', value: 'ok' }
162
282
  *
163
- * assert.deepStrictEqual(Option.getRight(Either.right('ok')), Option.some('ok'))
164
- * assert.deepStrictEqual(Option.getRight(Either.left('err')), Option.none())
283
+ * console.log(Option.getRight(Either.left("err")))
284
+ * // Output: { _id: 'Option', _tag: 'None' }
165
285
  * ```
166
286
  *
167
- * @category conversions
287
+ * @category Conversions
168
288
  * @since 2.0.0
169
289
  */
170
290
  export const getRight = either.getRight;
171
291
  /**
172
- * Converts a `Either` to an `Option` discarding the value.
292
+ * Converts an `Either` into an `Option` by discarding the right value and
293
+ * extracting the left value.
294
+ *
295
+ * **Details**
296
+ *
297
+ * This function transforms an `Either` into an `Option` as follows:
298
+ *
299
+ * - If the `Either` is a `Left`, its value is wrapped in a `Some` and returned.
300
+ * - If the `Either` is a `Right`, the value is discarded, and `None` is
301
+ * returned.
302
+ *
303
+ * This utility is useful when you only care about the error case (`Left`) of an
304
+ * `Either` and want to handle it as an `Option`. By discarding the right value,
305
+ * it simplifies error-focused workflows.
306
+ *
307
+ * @see {@link getRight} for the opposite operation.
173
308
  *
174
309
  * @example
175
310
  * ```ts
176
- * import { Option, Either } from "effect"
311
+ * import { Either, Option } from "effect"
177
312
  *
178
- * assert.deepStrictEqual(Option.getLeft(Either.right("ok")), Option.none())
179
- * assert.deepStrictEqual(Option.getLeft(Either.left("a")), Option.some("a"))
313
+ * console.log(Option.getLeft(Either.right("ok")))
314
+ * // Output: { _id: 'Option', _tag: 'None' }
315
+ *
316
+ * console.log(Option.getLeft(Either.left("err")))
317
+ * // Output: { _id: 'Option', _tag: 'Some', value: 'err' }
180
318
  * ```
181
319
  *
182
- * @category conversions
320
+ * @category Conversions
183
321
  * @since 2.0.0
184
322
  */
185
323
  export const getLeft = either.getLeft;
186
324
  /**
187
- * Returns the value of the `Option` if it is `Some`, otherwise returns `onNone`
325
+ * Returns the value contained in the `Option` if it is `Some`, otherwise
326
+ * evaluates and returns the result of `onNone`.
327
+ *
328
+ * **Details**
188
329
  *
189
- * @param self - The `Option` to get the value of.
190
- * @param onNone - Function that returns the default value to return if the `Option` is `None`.
330
+ * This function allows you to provide a fallback value or computation for when
331
+ * an `Option` is `None`. If the `Option` contains a value (`Some`), that value
332
+ * is returned. If it is empty (`None`), the `onNone` function is executed, and
333
+ * its result is returned instead.
334
+ *
335
+ * This utility is helpful for safely handling `Option` values by ensuring you
336
+ * always receive a meaningful result, whether or not the `Option` contains a
337
+ * value. It is particularly useful for providing default values or alternative
338
+ * logic when working with optional values.
339
+ *
340
+ * @see {@link getOrNull} for a version that returns `null` instead of executing a function.
341
+ * @see {@link getOrUndefined} for a version that returns `undefined` instead of executing a function.
191
342
  *
192
343
  * @example
193
344
  * ```ts
194
- * import { pipe, Option } from "effect"
345
+ * import { Option } from "effect"
195
346
  *
196
- * assert.deepStrictEqual(pipe(Option.some(1), Option.getOrElse(() => 0)), 1)
197
- * assert.deepStrictEqual(pipe(Option.none(), Option.getOrElse(() => 0)), 0)
347
+ * console.log(Option.some(1).pipe(Option.getOrElse(() => 0)))
348
+ * // Output: 1
349
+ *
350
+ * console.log(Option.none().pipe(Option.getOrElse(() => 0)))
351
+ * // Output: 0
198
352
  * ```
199
353
  *
200
- * @category getters
354
+ * @category Getters
201
355
  * @since 2.0.0
202
356
  */
203
357
  export const getOrElse = /*#__PURE__*/dual(2, (self, onNone) => isNone(self) ? onNone() : self.value);
204
358
  /**
205
- * Returns the provided `Option` `that` if `self` is `None`, otherwise returns `self`.
359
+ * Returns the provided `Option` `that` if the current `Option` (`self`) is
360
+ * `None`; otherwise, it returns `self`.
361
+ *
362
+ * **Details**
206
363
  *
207
- * @param self - The first `Option` to be checked.
208
- * @param that - The `Option` to return if `self` is `None`.
364
+ * This function provides a fallback mechanism for `Option` values. If the
365
+ * current `Option` is `None` (i.e., it contains no value), the `that` function
366
+ * is evaluated, and its resulting `Option` is returned. If the current `Option`
367
+ * is `Some` (i.e., it contains a value), the original `Option` is returned
368
+ * unchanged.
369
+ *
370
+ * This is particularly useful for chaining fallback values or computations,
371
+ * allowing you to provide alternative `Option` values when the first one is
372
+ * empty.
209
373
  *
210
374
  * @example
211
375
  * ```ts
212
- * import { pipe, Option } from "effect"
376
+ * import { Option } from "effect"
213
377
  *
214
- * assert.deepStrictEqual(
215
- * pipe(
216
- * Option.none(),
217
- * Option.orElse(() => Option.none())
218
- * ),
219
- * Option.none()
220
- * )
221
- * assert.deepStrictEqual(
222
- * pipe(
223
- * Option.some('a'),
224
- * Option.orElse(() => Option.none())
225
- * ),
226
- * Option.some('a')
227
- * )
228
- * assert.deepStrictEqual(
229
- * pipe(
230
- * Option.none(),
231
- * Option.orElse(() => Option.some('b'))
232
- * ),
233
- * Option.some('b')
234
- * )
235
- * assert.deepStrictEqual(
236
- * pipe(
237
- * Option.some('a'),
238
- * Option.orElse(() => Option.some('b'))
239
- * ),
240
- * Option.some('a')
241
- * )
378
+ * console.log(Option.none().pipe(Option.orElse(() => Option.none())))
379
+ * // Output: { _id: 'Option', _tag: 'None' }
380
+ *
381
+ * console.log(Option.some("a").pipe(Option.orElse(() => Option.none())))
382
+ * // Output: { _id: 'Option', _tag: 'Some', value: 'a' }
383
+ *
384
+ * console.log(Option.none().pipe(Option.orElse(() => Option.some("b"))))
385
+ * // Output: { _id: 'Option', _tag: 'Some', value: 'b' }
386
+ *
387
+ * console.log(Option.some("a").pipe(Option.orElse(() => Option.some("b"))))
388
+ * // Output: { _id: 'Option', _tag: 'Some', value: 'a' }
242
389
  * ```
243
390
  *
244
- * @category error handling
391
+ * @category Error handling
245
392
  * @since 2.0.0
246
393
  */
247
394
  export const orElse = /*#__PURE__*/dual(2, (self, that) => isNone(self) ? that() : self);
248
395
  /**
249
- * Returns the provided default value as `Some` if `self` is `None`, otherwise returns `self`.
396
+ * Returns the provided default value wrapped in `Some` if the current `Option`
397
+ * (`self`) is `None`; otherwise, returns `self`.
398
+ *
399
+ * **Details**
400
+ *
401
+ * This function provides a way to supply a default value for cases where an
402
+ * `Option` is `None`. If the current `Option` is empty (`None`), the `onNone`
403
+ * function is executed to compute the default value, which is then wrapped in a
404
+ * `Some`. If the current `Option` contains a value (`Some`), it is returned as
405
+ * is.
250
406
  *
251
- * @param self - The first `Option` to be checked.
252
- * @param onNone - Function that returns the default value to return if the `Option` is `None`.
407
+ * This is particularly useful for handling optional values where a fallback
408
+ * default needs to be provided explicitly in case of absence.
253
409
  *
254
410
  * @example
255
411
  * ```ts
256
- * import { pipe, Option } from "effect"
412
+ * import { Option } from "effect"
257
413
  *
258
- * assert.deepStrictEqual(
259
- * pipe(
260
- * Option.none(),
261
- * Option.orElseSome(() => 'b')
262
- * ),
263
- * Option.some('b')
264
- * )
265
- * assert.deepStrictEqual(
266
- * pipe(
267
- * Option.some('a'),
268
- * Option.orElseSome(() => 'b')
269
- * ),
270
- * Option.some('a')
271
- * )
414
+ * console.log(Option.none().pipe(Option.orElseSome(() => "b")))
415
+ * // Output: { _id: 'Option', _tag: 'Some', value: 'b' }
416
+ *
417
+ * console.log(Option.some("a").pipe(Option.orElseSome(() => "b")))
418
+ * // Output: { _id: 'Option', _tag: 'Some', value: 'a' }
272
419
  * ```
273
420
  *
274
- * @category error handling
421
+ * @category Error handling
275
422
  * @since 2.0.0
276
423
  */
277
424
  export const orElseSome = /*#__PURE__*/dual(2, (self, onNone) => isNone(self) ? some(onNone()) : self);
278
425
  /**
279
- * Similar to `orElse`, but instead of returning a simple union, it returns an `Either` object,
280
- * which contains information about which of the two `Option`s has been chosen.
426
+ * Similar to {@link orElse}, but returns an `Either` wrapped in an `Option` to
427
+ * indicate the source of the value.
281
428
  *
282
- * This is useful when it's important to know whether the value was retrieved from the first `Option` or the second option.
429
+ * **Details**
283
430
  *
284
- * @param self - The first `Option` to be checked.
285
- * @param that - The second `Option` to be considered if the first `Option` is `None`.
431
+ * This function allows you to provide a fallback `Option` in case the current
432
+ * `Option` (`self`) is `None`. However, unlike `orElse`, it returns the value
433
+ * wrapped in an `Either` object, providing additional information about where
434
+ * the value came from:
286
435
  *
287
- * @category error handling
436
+ * - If the value is from the fallback `Option` (`that`), it is wrapped in an
437
+ * `Either.right`.
438
+ * - If the value is from the original `Option` (`self`), it is wrapped in an
439
+ * `Either.left`.
440
+ *
441
+ * This is especially useful when you need to differentiate between values
442
+ * originating from the primary `Option` and those coming from the fallback,
443
+ * while still maintaining the `Option`-style handling.
444
+ *
445
+ * @category Error handling
288
446
  * @since 2.0.0
289
447
  */
290
448
  export const orElseEither = /*#__PURE__*/dual(2, (self, that) => isNone(self) ? map(that(), either.right) : map(self, either.left));
291
449
  /**
292
- * Given an `Iterable` collection of `Option`s, returns the first `Some` found in the collection.
450
+ * Returns the first `Some` value found in an `Iterable` collection of
451
+ * `Option`s, or `None` if no `Some` is found.
452
+ *
453
+ * **Details**
293
454
  *
294
- * @param collection - An iterable collection of `Option` to be searched.
455
+ * This function iterates over a collection of `Option` values and returns the
456
+ * first `Some` it encounters. If the collection contains only `None` values,
457
+ * the result will also be `None`. This utility is useful for efficiently
458
+ * finding the first valid value in a sequence of potentially empty or invalid
459
+ * options.
460
+ *
461
+ * The iteration stops as soon as a `Some` is found, making this function
462
+ * efficient for large collections.
295
463
  *
296
464
  * @example
297
465
  * ```ts
298
466
  * import { Option } from "effect"
299
467
  *
300
- * assert.deepStrictEqual(Option.firstSomeOf([Option.none(), Option.some(1), Option.some(2)]), Option.some(1))
468
+ * console.log(Option.firstSomeOf([
469
+ * Option.none(),
470
+ * Option.some(1),
471
+ * Option.some(2)
472
+ * ]))
473
+ * // Output: { _id: 'Option', _tag: 'Some', value: 1 }
301
474
  * ```
302
475
  *
303
- * @category error handling
476
+ * @category Error handling
304
477
  * @since 2.0.0
305
478
  */
306
479
  export const firstSomeOf = collection => {
@@ -313,26 +486,38 @@ export const firstSomeOf = collection => {
313
486
  return out;
314
487
  };
315
488
  /**
316
- * Constructs a new `Option` from a nullable type. If the value is `null` or `undefined`, returns `None`, otherwise
317
- * returns the value wrapped in a `Some`.
318
- *
319
- * @param nullableValue - The nullable value to be converted to an `Option`.
489
+ * Converts a nullable value into an `Option`. Returns `None` if the value is
490
+ * `null` or `undefined`, otherwise wraps the value in a `Some`.
320
491
  *
321
492
  * @example
322
493
  * ```ts
323
494
  * import { Option } from "effect"
324
495
  *
325
- * assert.deepStrictEqual(Option.fromNullable(undefined), Option.none())
326
- * assert.deepStrictEqual(Option.fromNullable(null), Option.none())
327
- * assert.deepStrictEqual(Option.fromNullable(1), Option.some(1))
496
+ * console.log(Option.fromNullable(undefined))
497
+ * // Output: { _id: 'Option', _tag: 'None' }
498
+ *
499
+ * console.log(Option.fromNullable(null))
500
+ * // Output: { _id: 'Option', _tag: 'None' }
501
+ *
502
+ * console.log(Option.fromNullable(1))
503
+ * // Output: { _id: 'Option', _tag: 'Some', value: 1 }
328
504
  * ```
329
505
  *
330
- * @category conversions
506
+ * @category Conversions
331
507
  * @since 2.0.0
332
508
  */
333
509
  export const fromNullable = nullableValue => nullableValue == null ? none() : some(nullableValue);
334
510
  /**
335
- * This API is useful for lifting a function that returns `null` or `undefined` into the `Option` context.
511
+ * Lifts a function that returns `null` or `undefined` into the `Option`
512
+ * context.
513
+ *
514
+ * **Details**
515
+ *
516
+ * This function takes a function `f` that might return `null` or `undefined`
517
+ * and transforms it into a function that returns an `Option`. The resulting
518
+ * function will return:
519
+ * - `Some` if the original function produces a non-null, non-undefined value.
520
+ * - `None` if the original function produces `null` or `undefined`.
336
521
  *
337
522
  * @example
338
523
  * ```ts
@@ -345,55 +530,84 @@ export const fromNullable = nullableValue => nullableValue == null ? none() : so
345
530
  *
346
531
  * const parseOption = Option.liftNullable(parse)
347
532
  *
348
- * assert.deepStrictEqual(parseOption('1'), Option.some(1))
349
- * assert.deepStrictEqual(parseOption('not a number'), Option.none())
533
+ * console.log(parseOption("1"))
534
+ * // Output: { _id: 'Option', _tag: 'Some', value: 1 }
535
+ *
536
+ * console.log(parseOption("not a number"))
537
+ * // Output: { _id: 'Option', _tag: 'None' }
350
538
  * ```
351
539
  *
352
- * @category conversions
540
+ * @category Conversions
353
541
  * @since 2.0.0
354
542
  */
355
543
  export const liftNullable = f => (...a) => fromNullable(f(...a));
356
544
  /**
357
- * Returns the value of the `Option` if it is a `Some`, otherwise returns `null`.
545
+ * Returns the value contained in the `Option` if it is `Some`; otherwise,
546
+ * returns `null`.
547
+ *
548
+ * **Details**
549
+ *
550
+ * This function provides a way to extract the value of an `Option` while
551
+ * falling back to `null` if the `Option` is `None`.
358
552
  *
359
- * @param self - The `Option` to extract the value from.
553
+ * It is particularly useful in scenarios where `null` is an acceptable
554
+ * placeholder for the absence of a value, such as when interacting with APIs or
555
+ * systems that use `null` as a default for missing values.
360
556
  *
361
557
  * @example
362
558
  * ```ts
363
559
  * import { Option } from "effect"
364
560
  *
365
- * assert.deepStrictEqual(Option.getOrNull(Option.some(1)), 1)
366
- * assert.deepStrictEqual(Option.getOrNull(Option.none()), null)
561
+ * console.log(Option.getOrNull(Option.some(1)))
562
+ * // Output: 1
563
+ *
564
+ * console.log(Option.getOrNull(Option.none()))
565
+ * // Output: null
367
566
  * ```
368
567
  *
369
- * @category getters
568
+ * @category Getters
370
569
  * @since 2.0.0
371
570
  */
372
571
  export const getOrNull = /*#__PURE__*/getOrElse(constNull);
373
572
  /**
374
- * Returns the value of the `Option` if it is a `Some`, otherwise returns `undefined`.
573
+ * Returns the value contained in the `Option` if it is `Some`; otherwise,
574
+ * returns `undefined`.
575
+ *
576
+ * **Details**
375
577
  *
376
- * @param self - The `Option` to extract the value from.
578
+ * This function provides a way to extract the value of an `Option` while
579
+ * falling back to `undefined` if the `Option` is `None`.
580
+ *
581
+ * It is particularly useful in scenarios where `undefined` is an acceptable
582
+ * placeholder for the absence of a value, such as when interacting with APIs or
583
+ * systems that use `undefined` as a default for missing values.
377
584
  *
378
585
  * @example
379
586
  * ```ts
380
587
  * import { Option } from "effect"
381
588
  *
382
- * assert.deepStrictEqual(Option.getOrUndefined(Option.some(1)), 1)
383
- * assert.deepStrictEqual(Option.getOrUndefined(Option.none()), undefined)
589
+ * console.log(Option.getOrUndefined(Option.some(1)))
590
+ * // Output: 1
591
+ *
592
+ * console.log(Option.getOrUndefined(Option.none()))
593
+ * // Output: undefined
384
594
  * ```
385
595
  *
386
- * @category getters
596
+ * @category Getters
387
597
  * @since 2.0.0
388
598
  */
389
599
  export const getOrUndefined = /*#__PURE__*/getOrElse(constUndefined);
390
600
  /**
391
- * A utility function that lifts a function that throws exceptions into a function that returns an `Option`.
601
+ * Lifts a function that throws exceptions into a function that returns an
602
+ * `Option`.
392
603
  *
393
- * This function is useful for any function that might throw an exception, allowing the developer to handle
394
- * the exception in a more functional way.
604
+ * **Details**
395
605
  *
396
- * @param f - the function that can throw exceptions.
606
+ * This utility function takes a function `f` that might throw an exception and
607
+ * transforms it into a safer function that returns an `Option`. If the original
608
+ * function executes successfully, the result is wrapped in a `Some`. If an
609
+ * exception is thrown, the result is `None`, allowing the developer to handle
610
+ * errors in a functional, type-safe way.
397
611
  *
398
612
  * @example
399
613
  * ```ts
@@ -401,11 +615,14 @@ export const getOrUndefined = /*#__PURE__*/getOrElse(constUndefined);
401
615
  *
402
616
  * const parse = Option.liftThrowable(JSON.parse)
403
617
  *
404
- * assert.deepStrictEqual(parse("1"), Option.some(1))
405
- * assert.deepStrictEqual(parse(""), Option.none())
618
+ * console.log(parse("1"))
619
+ * // Output: { _id: 'Option', _tag: 'Some', value: 1 }
620
+ *
621
+ * console.log(parse(""))
622
+ * // Output: { _id: 'Option', _tag: 'None' }
406
623
  * ```
407
624
  *
408
- * @category conversions
625
+ * @category Conversions
409
626
  * @since 2.0.0
410
627
  */
411
628
  export const liftThrowable = f => (...a) => {
@@ -416,12 +633,18 @@ export const liftThrowable = f => (...a) => {
416
633
  }
417
634
  };
418
635
  /**
419
- * Extracts the value of an `Option` or throws if the `Option` is `None`.
636
+ * Extracts the value of an `Option` or throws an error if the `Option` is
637
+ * `None`, using a custom error factory.
638
+ *
639
+ * **Details**
420
640
  *
421
- * If a default error is sufficient for your use case and you don't need to configure the thrown error, see {@link getOrThrow}.
641
+ * This function allows you to extract the value of an `Option` when it is
642
+ * `Some`. If the `Option` is `None`, it throws an error generated by the
643
+ * provided `onNone` function. This utility is particularly useful when you need
644
+ * a fail-fast behavior for empty `Option` values and want to provide a custom
645
+ * error message or object.
422
646
  *
423
- * @param self - The `Option` to extract the value from.
424
- * @param onNone - A function that will be called if the `Option` is `None`. It returns the error to be thrown.
647
+ * @see {@link getOrThrow} for a version that throws a default error.
425
648
  *
426
649
  * @example
427
650
  * ```ts
@@ -434,7 +657,7 @@ export const liftThrowable = f => (...a) => {
434
657
  * assert.throws(() => Option.getOrThrowWith(Option.none(), () => new Error('Unexpected None')))
435
658
  * ```
436
659
  *
437
- * @category conversions
660
+ * @category Conversions
438
661
  * @since 2.0.0
439
662
  */
440
663
  export const getOrThrowWith = /*#__PURE__*/dual(2, (self, onNone) => {
@@ -444,12 +667,17 @@ export const getOrThrowWith = /*#__PURE__*/dual(2, (self, onNone) => {
444
667
  throw onNone();
445
668
  });
446
669
  /**
447
- * Extracts the value of an `Option` or throws if the `Option` is `None`.
670
+ * Extracts the value of an `Option` or throws a default error if the `Option`
671
+ * is `None`.
448
672
  *
449
- * The thrown error is a default error. To configure the error thrown, see {@link getOrThrowWith}.
673
+ * **Details**
450
674
  *
451
- * @param self - The `Option` to extract the value from.
452
- * @throws `Error("getOrThrow called on a None")`
675
+ * This function extracts the value from an `Option` if it is `Some`. If the
676
+ * `Option` is `None`, it throws a default error. It is useful for fail-fast
677
+ * scenarios where the absence of a value is treated as an exceptional case and
678
+ * a default error is sufficient.
679
+ *
680
+ * @see {@link getOrThrowWith} for a version that allows you to provide a custom error.
453
681
  *
454
682
  * @example
455
683
  * ```ts
@@ -459,33 +687,92 @@ export const getOrThrowWith = /*#__PURE__*/dual(2, (self, onNone) => {
459
687
  * assert.throws(() => Option.getOrThrow(Option.none()))
460
688
  * ```
461
689
  *
462
- * @category conversions
690
+ * @category Conversions
463
691
  * @since 2.0.0
464
692
  */
465
693
  export const getOrThrow = /*#__PURE__*/getOrThrowWith(() => new Error("getOrThrow called on a None"));
466
694
  /**
467
- * Maps the `Some` side of an `Option` value to a new `Option` value.
695
+ * Transforms the value inside a `Some` to a new value using the provided
696
+ * function, while leaving `None` unchanged.
697
+ *
698
+ * **Details**
699
+ *
700
+ * This function applies a mapping function `f` to the value inside an `Option`
701
+ * if it is a `Some`. If the `Option` is `None`, it remains unchanged. The
702
+ * result is a new `Option` with the transformed value (if it was a `Some`) or
703
+ * still `None`.
704
+ *
705
+ * This utility is particularly useful for chaining transformations in a
706
+ * functional way without needing to manually handle `None` cases.
707
+ *
708
+ * @example
709
+ * ```ts
710
+ * import { Option } from "effect"
468
711
  *
469
- * @param self - An `Option` to map
470
- * @param f - The function to map over the value of the `Option`
712
+ * // Mapping over a `Some`
713
+ * const someValue = Option.some(2)
471
714
  *
472
- * @category mapping
715
+ * console.log(Option.map(someValue, (n) => n * 2))
716
+ * // Output: { _id: 'Option', _tag: 'Some', value: 4 }
717
+ *
718
+ * // Mapping over a `None`
719
+ * const noneValue = Option.none<number>()
720
+ *
721
+ * console.log(Option.map(noneValue, (n) => n * 2))
722
+ * // Output: { _id: 'Option', _tag: 'None' }
723
+ * ```
724
+ *
725
+ * @category Mapping
473
726
  * @since 2.0.0
474
727
  */
475
728
  export const map = /*#__PURE__*/dual(2, (self, f) => isNone(self) ? none() : some(f(self.value)));
476
729
  /**
477
- * Maps the `Some` value of this `Option` to the specified constant value.
730
+ * Replaces the value inside a `Some` with the specified constant value, leaving
731
+ * `None` unchanged.
732
+ *
733
+ * **Details**
478
734
  *
479
- * @category mapping
735
+ * This function transforms an `Option` by replacing the value inside a `Some`
736
+ * with the given constant value `b`. If the `Option` is `None`, it remains
737
+ * unchanged.
738
+ *
739
+ * This is useful when you want to preserve the presence of a value (`Some`) but
740
+ * replace its content with a fixed value.
741
+ *
742
+ * @example
743
+ * ```ts
744
+ * import { Option } from "effect"
745
+ *
746
+ * // Replacing the value of a `Some`
747
+ * const someValue = Option.some(42)
748
+ *
749
+ * console.log(Option.as(someValue, "new value"))
750
+ * // Output: { _id: 'Option', _tag: 'Some', value: 'new value' }
751
+ *
752
+ * // Replacing a `None` (no effect)
753
+ * const noneValue = Option.none<number>()
754
+ *
755
+ * console.log(Option.as(noneValue, "new value"))
756
+ * // Output: { _id: 'Option', _tag: 'None' }
757
+ * ```
758
+ *
759
+ * @category Mapping
480
760
  * @since 2.0.0
481
761
  */
482
762
  export const as = /*#__PURE__*/dual(2, (self, b) => map(self, () => b));
483
763
  /**
484
- * Maps the `Some` value of this `Option` to the `void` constant value.
764
+ * Replaces the value inside a `Some` with the constant value `void`, leaving
765
+ * `None` unchanged.
766
+ *
767
+ * **Details**
485
768
  *
486
- * This is useful when the value of the `Option` is not needed, but the presence or absence of the value is important.
769
+ * This function transforms an `Option` by replacing the value inside a `Some`
770
+ * with `void`. If the `Option` is `None`, it remains unchanged.
487
771
  *
488
- * @category mapping
772
+ * This is particularly useful in scenarios where the presence or absence of a
773
+ * value is significant, but the actual content of the value is irrelevant.
774
+ *
775
+ * @category Mapping
489
776
  * @since 2.0.0
490
777
  */
491
778
  export const asVoid = /*#__PURE__*/as(undefined);
@@ -496,16 +783,77 @@ export {
496
783
  */
497
784
  void_ as void };
498
785
  /**
499
- * Applies a function to the value of an `Option` and flattens the result, if the input is `Some`.
786
+ * Applies a function to the value of a `Some` and flattens the resulting
787
+ * `Option`. If the input is `None`, it remains `None`.
788
+ *
789
+ * **Details**
790
+ *
791
+ * This function allows you to chain computations that return `Option` values.
792
+ * If the input `Option` is `Some`, the provided function `f` is applied to the
793
+ * contained value, and the resulting `Option` is returned. If the input is
794
+ * `None`, the function is not applied, and the result remains `None`.
795
+ *
796
+ * This utility is particularly useful for sequencing operations that may fail
797
+ * or produce optional results, enabling clean and concise workflows for
798
+ * handling such cases.
799
+ *
800
+ * @example
801
+ * ```ts
802
+ * import { Option } from "effect"
803
+ *
804
+ * interface Address {
805
+ * readonly city: string
806
+ * readonly street: Option.Option<string>
807
+ * }
808
+ *
809
+ * interface User {
810
+ * readonly id: number
811
+ * readonly username: string
812
+ * readonly email: Option.Option<string>
813
+ * readonly address: Option.Option<Address>
814
+ * }
815
+ *
816
+ * const user: User = {
817
+ * id: 1,
818
+ * username: "john_doe",
819
+ * email: Option.some("john.doe@example.com"),
820
+ * address: Option.some({
821
+ * city: "New York",
822
+ * street: Option.some("123 Main St")
823
+ * })
824
+ * }
825
+ *
826
+ * // Use flatMap to extract the street value
827
+ * const street = user.address.pipe(
828
+ * Option.flatMap((address) => address.street)
829
+ * )
830
+ *
831
+ * console.log(street)
832
+ * // Output: { _id: 'Option', _tag: 'Some', value: '123 Main St' }
833
+ * ```
500
834
  *
501
- * @category sequencing
835
+ * @category Sequencing
502
836
  * @since 2.0.0
503
837
  */
504
838
  export const flatMap = /*#__PURE__*/dual(2, (self, f) => isNone(self) ? none() : f(self.value));
505
839
  /**
506
- * Executes a sequence of two `Option`s. The second `Option` can be dependent on the result of the first `Option`.
840
+ * Chains two `Option`s together. The second `Option` can either be a static
841
+ * value or depend on the result of the first `Option`.
842
+ *
843
+ * **Details**
844
+ *
845
+ * This function enables sequencing of two `Option` computations. If the first
846
+ * `Option` is `Some`, the second `Option` is evaluated. The second `Option` can
847
+ * either:
848
+ *
849
+ * - Be a static `Option` value.
850
+ * - Be a function that produces an `Option`, optionally based on the value of
851
+ * the first `Option`.
852
+ *
853
+ * If the first `Option` is `None`, the function skips the evaluation of the
854
+ * second `Option` and directly returns `None`.
507
855
  *
508
- * @category sequencing
856
+ * @category Sequencing
509
857
  * @since 2.0.0
510
858
  */
511
859
  export const andThen = /*#__PURE__*/dual(2, (self, f) => flatMap(self, a => {
@@ -513,11 +861,24 @@ export const andThen = /*#__PURE__*/dual(2, (self, f) => flatMap(self, a => {
513
861
  return isOption(b) ? b : some(b);
514
862
  }));
515
863
  /**
516
- * This is `flatMap` + `fromNullable`, useful when working with optional values.
864
+ * Combines `flatMap` and `fromNullable`, transforming the value inside a `Some`
865
+ * using a function that may return `null` or `undefined`.
866
+ *
867
+ * **Details**
868
+ *
869
+ * This function applies a transformation function `f` to the value inside a
870
+ * `Some`. The function `f` may return a value, `null`, or `undefined`. If `f`
871
+ * returns a value, it is wrapped in a `Some`. If `f` returns `null` or
872
+ * `undefined`, the result is `None`. If the input `Option` is `None`, the
873
+ * function is not applied, and `None` is returned.
874
+ *
875
+ * This utility is particularly useful when working with deeply nested optional
876
+ * values or chaining computations that may result in `null` or `undefined` at
877
+ * some point.
517
878
  *
518
879
  * @example
519
880
  * ```ts
520
- * import { pipe, Option } from "effect"
881
+ * import { Option } from "effect"
521
882
  *
522
883
  * interface Employee {
523
884
  * company?: {
@@ -529,66 +890,133 @@ export const andThen = /*#__PURE__*/dual(2, (self, f) => flatMap(self, a => {
529
890
  * }
530
891
  * }
531
892
  *
532
- * const employee1: Employee = { company: { address: { street: { name: 'high street' } } } }
893
+ * const employee1: Employee = { company: { address: { street: { name: "high street" } } } }
533
894
  *
534
- * assert.deepStrictEqual(
535
- * pipe(
536
- * Option.some(employee1),
537
- * Option.flatMapNullable(employee => employee.company?.address?.street?.name),
538
- * ),
539
- * Option.some('high street')
895
+ * // Extracting a deeply nested property
896
+ * console.log(
897
+ * Option.some(employee1)
898
+ * .pipe(Option.flatMapNullable((employee) => employee.company?.address?.street?.name))
540
899
  * )
900
+ * // Output: { _id: 'Option', _tag: 'Some', value: 'high street' }
541
901
  *
542
902
  * const employee2: Employee = { company: { address: { street: {} } } }
543
903
  *
544
- * assert.deepStrictEqual(
545
- * pipe(
546
- * Option.some(employee2),
547
- * Option.flatMapNullable(employee => employee.company?.address?.street?.name),
548
- * ),
549
- * Option.none()
904
+ * // Property does not exist
905
+ * console.log(
906
+ * Option.some(employee2)
907
+ * .pipe(Option.flatMapNullable((employee) => employee.company?.address?.street?.name))
550
908
  * )
909
+ * // Output: { _id: 'Option', _tag: 'None' }
551
910
  * ```
552
911
  *
553
- * @category sequencing
912
+ * @category Sequencing
554
913
  * @since 2.0.0
555
914
  */
556
915
  export const flatMapNullable = /*#__PURE__*/dual(2, (self, f) => isNone(self) ? none() : fromNullable(f(self.value)));
557
916
  /**
558
- * @category sequencing
917
+ * Flattens an `Option` of `Option` into a single `Option`.
918
+ *
919
+ * **Details**
920
+ *
921
+ * This function takes an `Option` that wraps another `Option` and flattens it
922
+ * into a single `Option`. If the outer `Option` is `Some`, the function
923
+ * extracts the inner `Option`. If the outer `Option` is `None`, the result
924
+ * remains `None`.
925
+ *
926
+ * This is useful for simplifying nested `Option` structures that may arise
927
+ * during functional operations.
928
+ *
929
+ * @category Sequencing
559
930
  * @since 2.0.0
560
931
  */
561
932
  export const flatten = /*#__PURE__*/flatMap(identity);
562
933
  /**
563
- * @category zipping
934
+ * Combines two `Option`s, keeping the value from the second `Option` if both
935
+ * are `Some`.
936
+ *
937
+ * **Details**
938
+ *
939
+ * This function takes two `Option`s and returns the second one if the first is
940
+ * `Some`. If the first `Option` is `None`, the result will also be `None`,
941
+ * regardless of the second `Option`. It effectively "zips" the two `Option`s
942
+ * while discarding the value from the first `Option`.
943
+ *
944
+ * This is particularly useful when sequencing computations where the result of
945
+ * the first computation is not needed, and you only care about the result of
946
+ * the second computation.
947
+ *
948
+ * @category Zipping
564
949
  * @since 2.0.0
565
950
  */
566
951
  export const zipRight = /*#__PURE__*/dual(2, (self, that) => flatMap(self, () => that));
567
952
  /**
568
- * @category sequencing
953
+ * Combines two `Option`s, keeping the value from the first `Option` if both are
954
+ * `Some`.
955
+ *
956
+ * **Details**
957
+ *
958
+ * This function takes two `Option`s and returns the first one if it is `Some`.
959
+ * If either the first `Option` or the second `Option` is `None`, the result
960
+ * will be `None`. This operation "zips" the two `Option`s while discarding the
961
+ * value from the second `Option`.
962
+ *
963
+ * This is useful when sequencing computations where the second `Option`
964
+ * represents a dependency or condition that must hold, but its value is
965
+ * irrelevant.
966
+ *
967
+ * @category Zipping
569
968
  * @since 2.0.0
570
969
  */
571
- export const composeK = /*#__PURE__*/dual(2, (afb, bfc) => a => flatMap(afb(a), bfc));
970
+ export const zipLeft = /*#__PURE__*/dual(2, (self, that) => tap(self, () => that));
572
971
  /**
573
- * Sequences the specified `that` `Option` but ignores its value.
972
+ * Composes two functions that return `Option` values, creating a new function
973
+ * that chains them together.
574
974
  *
575
- * It is useful when we want to chain multiple operations, but only care about the result of `self`.
975
+ * **Details**
576
976
  *
577
- * @param that - The `Option` that will be ignored in the chain and discarded
578
- * @param self - The `Option` we care about
977
+ * This function allows you to compose two computations, each represented by a
978
+ * function that returns an `Option`. The result of the first function is passed
979
+ * to the second function if it is `Some`. If the first function returns `None`,
980
+ * the composed function short-circuits and returns `None` without invoking the
981
+ * second function.
982
+ *
983
+ * @example
984
+ * ```ts
985
+ * import { Option } from "effect"
986
+ *
987
+ * const parse = (s: string): Option.Option<number> => isNaN(Number(s)) ? Option.none() : Option.some(Number(s))
988
+ *
989
+ * const double = (n: number): Option.Option<number> => n > 0 ? Option.some(n * 2) : Option.none()
990
+ *
991
+ * const parseAndDouble = Option.composeK(parse, double)
992
+ *
993
+ * console.log(parseAndDouble("42"))
994
+ * // Output: { _id: 'Option', _tag: 'Some', value: 84 }
995
+ *
996
+ * console.log(parseAndDouble("not a number"))
997
+ * // Output: { _id: 'Option', _tag: 'None' }
998
+ * ```
579
999
  *
580
- * @category zipping
1000
+ * @category Sequencing
581
1001
  * @since 2.0.0
582
1002
  */
583
- export const zipLeft = /*#__PURE__*/dual(2, (self, that) => tap(self, () => that));
1003
+ export const composeK = /*#__PURE__*/dual(2, (afb, bfc) => a => flatMap(afb(a), bfc));
584
1004
  /**
585
- * Applies the provided function `f` to the value of the `Option` if it is `Some` and returns the original `Option`
586
- * unless `f` returns `None`, in which case it returns `None`.
1005
+ * Applies the provided function `f` to the value of the `Option` if it is
1006
+ * `Some` and returns the original `Option`, unless `f` returns `None`, in which
1007
+ * case it returns `None`.
1008
+ *
1009
+ * **Details**
587
1010
  *
588
- * This function is useful for performing additional computations on the value of the input `Option` without affecting its value.
1011
+ * This function allows you to perform additional computations on the value of
1012
+ * an `Option` without modifying its original value. If the `Option` is `Some`,
1013
+ * the provided function `f` is executed with the value, and its result
1014
+ * determines whether the original `Option` is returned (`Some`) or the result
1015
+ * is `None` if `f` returns `None`. If the input `Option` is `None`, the
1016
+ * function is not executed, and `None` is returned.
589
1017
  *
590
- * @param f - Function to apply to the value of the `Option` if it is `Some`
591
- * @param self - The `Option` to apply the function to
1018
+ * This is particularly useful for applying side conditions or performing
1019
+ * validation checks while retaining the original `Option`'s value.
592
1020
  *
593
1021
  * @example
594
1022
  * ```ts
@@ -596,22 +1024,47 @@ export const zipLeft = /*#__PURE__*/dual(2, (self, that) => tap(self, () => that
596
1024
  *
597
1025
  * const getInteger = (n: number) => Number.isInteger(n) ? Option.some(n) : Option.none()
598
1026
  *
599
- * assert.deepStrictEqual(Option.tap(Option.none(), getInteger), Option.none())
600
- * assert.deepStrictEqual(Option.tap(Option.some(1), getInteger), Option.some(1))
601
- * assert.deepStrictEqual(Option.tap(Option.some(1.14), getInteger), Option.none())
1027
+ * console.log(Option.tap(Option.none(), getInteger))
1028
+ * // Output: { _id: 'Option', _tag: 'None' }
1029
+ *
1030
+ * console.log(Option.tap(Option.some(1), getInteger))
1031
+ * // Output: { _id: 'Option', _tag: 'Some', value: 1 }
1032
+ *
1033
+ * console.log(Option.tap(Option.some(1.14), getInteger))
1034
+ * // Output: { _id: 'Option', _tag: 'None' }
602
1035
  * ```
603
1036
  *
604
- * @category sequencing
1037
+ * @category Sequencing
605
1038
  * @since 2.0.0
606
1039
  */
607
1040
  export const tap = /*#__PURE__*/dual(2, (self, f) => flatMap(self, a => map(f(a), () => a)));
608
1041
  /**
609
- * @category combining
1042
+ * Combines two `Option` values into a single `Option` containing a tuple of
1043
+ * their values if both are `Some`.
1044
+ *
1045
+ * **Details**
1046
+ *
1047
+ * This function takes two `Option`s and combines their values into a tuple `[A,
1048
+ * B]` if both are `Some`. If either of the `Option`s is `None`, the result is
1049
+ * `None`. This is particularly useful for combining multiple `Option` values
1050
+ * into a single one, ensuring both contain valid values.
1051
+ *
1052
+ * @category Combining
610
1053
  * @since 2.0.0
611
1054
  */
612
1055
  export const product = (self, that) => isSome(self) && isSome(that) ? some([self.value, that.value]) : none();
613
1056
  /**
614
- * @category combining
1057
+ * Combines an `Option` with a collection of `Option`s into a single `Option`
1058
+ * containing a tuple of their values if all are `Some`.
1059
+ *
1060
+ * **Details**
1061
+ *
1062
+ * This function takes a primary `Option` and a collection of `Option`s and
1063
+ * combines their values into a tuple `[A, ...Array<A>]` if all are `Some`. If
1064
+ * the primary `Option` or any `Option` in the collection is `None`, the result
1065
+ * is `None`.
1066
+ *
1067
+ * @category Combining
615
1068
  * @since 2.0.0
616
1069
  */
617
1070
  export const productMany = (self, collection) => {
@@ -628,24 +1081,47 @@ export const productMany = (self, collection) => {
628
1081
  return some(out);
629
1082
  };
630
1083
  /**
631
- * Takes a structure of `Option`s and returns an `Option` of values with the same structure.
1084
+ * Combines a structure of `Option`s into a single `Option` containing the
1085
+ * values with the same structure.
1086
+ *
1087
+ * **Details**
632
1088
  *
633
- * - If a tuple is supplied, then the returned `Option` will contain a tuple with the same length.
634
- * - If a struct is supplied, then the returned `Option` will contain a struct with the same keys.
635
- * - If an iterable is supplied, then the returned `Option` will contain an array.
1089
+ * This function takes a structure of `Option`s (a tuple, struct, or iterable)
1090
+ * and produces a single `Option` that contains the values from the input
1091
+ * structure if all `Option`s are `Some`. If any `Option` in the input is
1092
+ * `None`, the result is `None`. The structure of the input is preserved in the
1093
+ * output.
636
1094
  *
637
- * @param fields - the struct of `Option`s to be sequenced.
1095
+ * - If the input is a tuple (e.g., an array), the result will be an `Option`
1096
+ * containing a tuple with the same length.
1097
+ * - If the input is a struct (e.g., an object), the result will be an `Option`
1098
+ * containing a struct with the same keys.
1099
+ * - If the input is an iterable, the result will be an `Option` containing an
1100
+ * array.
638
1101
  *
639
1102
  * @example
640
1103
  * ```ts
641
1104
  * import { Option } from "effect"
642
1105
  *
643
- * assert.deepStrictEqual(Option.all([Option.some(1), Option.some(2)]), Option.some([1, 2]))
644
- * assert.deepStrictEqual(Option.all({ a: Option.some(1), b: Option.some("hello") }), Option.some({ a: 1, b: "hello" }))
645
- * assert.deepStrictEqual(Option.all({ a: Option.some(1), b: Option.none() }), Option.none())
1106
+ * const maybeName: Option.Option<string> = Option.some("John")
1107
+ * const maybeAge: Option.Option<number> = Option.some(25)
1108
+ *
1109
+ * // ┌─── Option<[string, number]>
1110
+ * // ▼
1111
+ * const tuple = Option.all([maybeName, maybeAge])
1112
+ * console.log(tuple)
1113
+ * // Output:
1114
+ * // { _id: 'Option', _tag: 'Some', value: [ 'John', 25 ] }
1115
+ *
1116
+ * // ┌─── Option<{ name: string; age: number; }>
1117
+ * // ▼
1118
+ * const struct = Option.all({ name: maybeName, age: maybeAge })
1119
+ * console.log(struct)
1120
+ * // Output:
1121
+ * // { _id: 'Option', _tag: 'Some', value: { name: 'John', age: 25 } }
646
1122
  * ```
647
1123
  *
648
- * @category combining
1124
+ * @category Combining
649
1125
  * @since 2.0.0
650
1126
  */
651
1127
  // @ts-expect-error
@@ -671,53 +1147,81 @@ export const all = input => {
671
1147
  return some(out);
672
1148
  };
673
1149
  /**
674
- * Zips two `Option` values together using a provided function, returning a new `Option` of the result.
1150
+ * Combines two `Option` values into a new `Option` by applying a provided
1151
+ * function to their values.
1152
+ *
1153
+ * **Details**
1154
+ *
1155
+ * This function takes two `Option` values (`self` and `that`) and a combining
1156
+ * function `f`. If both `Option` values are `Some`, the function `f` is applied
1157
+ * to their values, and the result is wrapped in a new `Some`. If either
1158
+ * `Option` is `None`, the result is `None`.
675
1159
  *
676
- * @param self - The left-hand side of the zip operation
677
- * @param that - The right-hand side of the zip operation
678
- * @param f - The function used to combine the values of the two `Option`s
1160
+ * This utility is useful for combining two optional computations into a single
1161
+ * result while maintaining type safety and avoiding explicit checks for `None`.
679
1162
  *
680
1163
  * @example
681
1164
  * ```ts
682
1165
  * import { Option } from "effect"
683
1166
  *
684
- * type Complex = [real: number, imaginary: number]
1167
+ * const maybeName: Option.Option<string> = Option.some("John")
1168
+ * const maybeAge: Option.Option<number> = Option.some(25)
685
1169
  *
686
- * const complex = (real: number, imaginary: number): Complex => [real, imaginary]
1170
+ * // Combine the name and age into a person object
1171
+ * const person = Option.zipWith(maybeName, maybeAge, (name, age) => ({
1172
+ * name: name.toUpperCase(),
1173
+ * age
1174
+ * }))
687
1175
  *
688
- * assert.deepStrictEqual(Option.zipWith(Option.none(), Option.none(), complex), Option.none())
689
- * assert.deepStrictEqual(Option.zipWith(Option.some(1), Option.none(), complex), Option.none())
690
- * assert.deepStrictEqual(Option.zipWith(Option.none(), Option.some(1), complex), Option.none())
691
- * assert.deepStrictEqual(Option.zipWith(Option.some(1), Option.some(2), complex), Option.some([1, 2]))
692
- *
693
- * assert.deepStrictEqual(Option.zipWith(Option.some(1), complex)(Option.some(2)), Option.some([2, 1]))
1176
+ * console.log(person)
1177
+ * // Output:
1178
+ * // { _id: 'Option', _tag: 'Some', value: { name: 'JOHN', age: 25 } }
694
1179
  * ```
695
1180
  *
696
- * @category zipping
1181
+ * @category Zipping
697
1182
  * @since 2.0.0
698
1183
  */
699
1184
  export const zipWith = /*#__PURE__*/dual(3, (self, that, f) => map(product(self, that), ([a, b]) => f(a, b)));
700
1185
  /**
701
- * @category combining
1186
+ * Applies a function inside a `Some` to a value inside another `Some`,
1187
+ * combining them into a new `Option`.
1188
+ *
1189
+ * **Details**
1190
+ *
1191
+ * This function allows you to apply a function wrapped in an `Option` (`self`)
1192
+ * to a value wrapped in another `Option` (`that`). If both `Option`s are
1193
+ * `Some`, the function is applied to the value, and the result is wrapped in a
1194
+ * new `Some`. If either `Option` is `None`, the result is `None`.
1195
+ *
1196
+ * @category Combining
702
1197
  * @since 2.0.0
703
1198
  */
704
1199
  export const ap = /*#__PURE__*/dual(2, (self, that) => zipWith(self, that, (f, a) => f(a)));
705
1200
  /**
706
- * Reduces an `Iterable` of `Option<A>` to a single value of type `B`, elements that are `None` are ignored.
1201
+ * Reduces an `Iterable` of `Option<A>` to a single value of type `B`, ignoring
1202
+ * elements that are `None`.
707
1203
  *
708
- * @param self - The Iterable of `Option<A>` to be reduced.
709
- * @param b - The initial value of the accumulator.
710
- * @param f - The reducing function that takes the current accumulator value and the unwrapped value of an `Option<A>`.
1204
+ * **Details**
1205
+ *
1206
+ * This function takes an initial value of type `B` and a reducing function `f`
1207
+ * that combines the accumulator with values of type `A`. It processes an
1208
+ * iterable of `Option<A>`, applying `f` only to the `Some` values while
1209
+ * ignoring the `None` values. The result is a single value of type `B`.
1210
+ *
1211
+ * This utility is particularly useful for aggregating values from an iterable
1212
+ * of `Option`s while skipping the absent (`None`) values.
711
1213
  *
712
1214
  * @example
713
1215
  * ```ts
714
- * import { pipe, Option } from "effect"
1216
+ * import { Option, pipe } from "effect"
715
1217
  *
716
1218
  * const iterable = [Option.some(1), Option.none(), Option.some(2), Option.none()]
717
- * assert.deepStrictEqual(pipe(iterable, Option.reduceCompact(0, (b, a) => b + a)), 3)
1219
+ *
1220
+ * console.log(pipe(iterable, Option.reduceCompact(0, (b, a) => b + a)))
1221
+ * // Output: 3
718
1222
  * ```
719
1223
  *
720
- * @category folding
1224
+ * @category Reducing
721
1225
  * @since 2.0.0
722
1226
  */
723
1227
  export const reduceCompact = /*#__PURE__*/dual(3, (self, b, f) => {
@@ -730,26 +1234,45 @@ export const reduceCompact = /*#__PURE__*/dual(3, (self, b, f) => {
730
1234
  return out;
731
1235
  });
732
1236
  /**
733
- * Transforms an `Option` into an `Array`.
1237
+ * Converts an `Option` into an `Array`.
734
1238
  * If the input is `None`, an empty array is returned.
735
- * If the input is `Some`, the value is wrapped in an array.
736
- *
737
- * @param self - The `Option` to convert to an array.
1239
+ * If the input is `Some`, its value is wrapped in a single-element array.
738
1240
  *
739
1241
  * @example
740
1242
  * ```ts
741
1243
  * import { Option } from "effect"
742
1244
  *
743
- * assert.deepStrictEqual(Option.toArray(Option.some(1)), [1])
744
- * assert.deepStrictEqual(Option.toArray(Option.none()), [])
1245
+ * console.log(Option.toArray(Option.some(1)))
1246
+ * // Output: [1]
1247
+ *
1248
+ * console.log(Option.toArray(Option.none()))
1249
+ * // Output: []
745
1250
  * ```
746
1251
  *
747
- * @category conversions
1252
+ * @category Conversions
748
1253
  * @since 2.0.0
749
1254
  */
750
1255
  export const toArray = self => isNone(self) ? [] : [self.value];
751
1256
  /**
752
- * @category filtering
1257
+ * Splits an `Option` into two `Option`s based on the result of a mapping
1258
+ * function that produces an `Either`.
1259
+ *
1260
+ * **Details**
1261
+ *
1262
+ * This function takes an `Option` and a mapping function `f` that converts its
1263
+ * value into an `Either`. It returns a tuple of two `Option`s:
1264
+ *
1265
+ * - The first `Option` (`left`) contains the value from the `Left` side of the
1266
+ * `Either` if it exists, otherwise `None`.
1267
+ * - The second `Option` (`right`) contains the value from the `Right` side of
1268
+ * the `Either` if it exists, otherwise `None`.
1269
+ *
1270
+ * If the input `Option` is `None`, both returned `Option`s are `None`.
1271
+ *
1272
+ * This utility is useful for filtering and categorizing the contents of an
1273
+ * `Option` based on a bifurcating computation.
1274
+ *
1275
+ * @category Filtering
753
1276
  * @since 2.0.0
754
1277
  */
755
1278
  export const partitionMap = /*#__PURE__*/dual(2, (self, f) => {
@@ -760,25 +1283,40 @@ export const partitionMap = /*#__PURE__*/dual(2, (self, f) => {
760
1283
  return either.isLeft(e) ? [some(e.left), none()] : [none(), some(e.right)];
761
1284
  });
762
1285
  /**
763
- * Maps over the value of an `Option` and filters out `None`s.
1286
+ * Maps over the value of an `Option` with a function that may return `None`,
1287
+ * effectively filtering and transforming the value.
1288
+ *
1289
+ * **Details**
764
1290
  *
765
- * Useful when in addition to filtering you also want to change the type of the `Option`.
1291
+ * This function allows you to both transform the value of a `Some` and filter
1292
+ * it at the same time. The mapping function `f` can either return a new
1293
+ * `Option` (to transform the value) or return `None` to filter it out. If the
1294
+ * input `Option` is `None`, the function is not applied, and the result remains
1295
+ * `None`.
766
1296
  *
767
- * @param self - The `Option` to map over.
768
- * @param f - A function to apply to the value of the `Option`.
1297
+ * This utility is particularly useful when you want to apply a transformation
1298
+ * to the value of an `Option` while conditionally removing invalid or unwanted
1299
+ * results.
769
1300
  *
770
1301
  * @example
771
1302
  * ```ts
772
1303
  * import { Option } from "effect"
773
1304
  *
774
- * const evenNumber = (n: number) => n % 2 === 0 ? Option.some(n) : Option.none()
1305
+ * // Transform and filter numbers
1306
+ * const transformEven = (n: Option.Option<number>): Option.Option<string> =>
1307
+ * Option.flatMap(n, (n) => (n % 2 === 0 ? Option.some(`Even: ${n}`) : Option.none()))
775
1308
  *
776
- * assert.deepStrictEqual(Option.filterMap(Option.none(), evenNumber), Option.none())
777
- * assert.deepStrictEqual(Option.filterMap(Option.some(3), evenNumber), Option.none())
778
- * assert.deepStrictEqual(Option.filterMap(Option.some(2), evenNumber), Option.some(2))
1309
+ * console.log(transformEven(Option.none()))
1310
+ * // Output: { _id: 'Option', _tag: 'None' }
1311
+ *
1312
+ * console.log(transformEven(Option.some(1)))
1313
+ * // Output: { _id: 'Option', _tag: 'None' }
1314
+ *
1315
+ * console.log(transformEven(Option.some(2)))
1316
+ * // Output: { _id: 'Option', _tag: 'Some', value: 'Even: 2' }
779
1317
  * ```
780
1318
  *
781
- * @category filtering
1319
+ * @category Filtering
782
1320
  * @since 2.0.0
783
1321
  */
784
1322
  export const filterMap = /*#__PURE__*/dual(2, (self, f) => isNone(self) ? none() : f(self.value));
@@ -787,146 +1325,273 @@ export const filterMap = /*#__PURE__*/dual(2, (self, f) => isNone(self) ? none()
787
1325
  *
788
1326
  * If you need to change the type of the `Option` in addition to filtering, see `filterMap`.
789
1327
  *
790
- * @param predicate - A predicate function to apply to the `Option` value.
791
- * @param fb - The `Option` to filter.
792
- *
793
1328
  * @example
794
1329
  * ```ts
795
1330
  * import { Option } from "effect"
796
1331
  *
797
- * // predicate
798
- * const isEven = (n: number) => n % 2 === 0
1332
+ * const removeEmptyString = (input: Option.Option<string>) =>
1333
+ * Option.filter(input, (value) => value !== "")
799
1334
  *
800
- * assert.deepStrictEqual(Option.filter(Option.none(), isEven), Option.none())
801
- * assert.deepStrictEqual(Option.filter(Option.some(3), isEven), Option.none())
802
- * assert.deepStrictEqual(Option.filter(Option.some(2), isEven), Option.some(2))
1335
+ * console.log(removeEmptyString(Option.none()))
1336
+ * // Output: { _id: 'Option', _tag: 'None' }
803
1337
  *
804
- * // refinement
805
- * const isNumber = (v: unknown): v is number => typeof v === "number"
1338
+ * console.log(removeEmptyString(Option.some("")))
1339
+ * // Output: { _id: 'Option', _tag: 'None' }
806
1340
  *
807
- * assert.deepStrictEqual(Option.filter(Option.none(), isNumber), Option.none())
808
- * assert.deepStrictEqual(Option.filter(Option.some('hello'), isNumber), Option.none())
809
- * assert.deepStrictEqual(Option.filter(Option.some(2), isNumber), Option.some(2))
1341
+ * console.log(removeEmptyString(Option.some("a")))
1342
+ * // Output: { _id: 'Option', _tag: 'Some', value: 'a' }
810
1343
  * ```
811
1344
  *
812
- * @category filtering
1345
+ * @category Filtering
813
1346
  * @since 2.0.0
814
1347
  */
815
1348
  export const filter = /*#__PURE__*/dual(2, (self, predicate) => filterMap(self, b => predicate(b) ? option.some(b) : option.none));
816
1349
  /**
1350
+ * Creates an `Equivalence` instance for comparing `Option` values, using a
1351
+ * provided `Equivalence` for the inner type.
1352
+ *
1353
+ * **Details**
1354
+ *
1355
+ * This function takes an `Equivalence` instance for a specific type `A` and
1356
+ * produces an `Equivalence` instance for `Option<A>`. The resulting
1357
+ * `Equivalence` determines whether two `Option` values are equivalent:
1358
+ *
1359
+ * - Two `None`s are considered equivalent.
1360
+ * - A `Some` and a `None` are not equivalent.
1361
+ * - Two `Some` values are equivalent if their inner values are equivalent
1362
+ * according to the provided `Equivalence`.
1363
+ *
817
1364
  * @example
818
1365
  * ```ts
819
- * import { Option, Number } from "effect"
1366
+ * // Title: Comparing Optional Numbers for Equivalence
1367
+ * import { Number, Option } from "effect"
820
1368
  *
821
1369
  * const isEquivalent = Option.getEquivalence(Number.Equivalence)
822
- * assert.deepStrictEqual(isEquivalent(Option.none(), Option.none()), true)
823
- * assert.deepStrictEqual(isEquivalent(Option.none(), Option.some(1)), false)
824
- * assert.deepStrictEqual(isEquivalent(Option.some(1), Option.none()), false)
825
- * assert.deepStrictEqual(isEquivalent(Option.some(1), Option.some(2)), false)
826
- * assert.deepStrictEqual(isEquivalent(Option.some(1), Option.some(1)), true)
1370
+ *
1371
+ * console.log(isEquivalent(Option.none(), Option.none()))
1372
+ * // Output: true
1373
+ *
1374
+ * console.log(isEquivalent(Option.none(), Option.some(1)))
1375
+ * // Output: false
1376
+ *
1377
+ * console.log(isEquivalent(Option.some(1), Option.none()))
1378
+ * // Output: false
1379
+ *
1380
+ * console.log(isEquivalent(Option.some(1), Option.some(2)))
1381
+ * // Output: false
1382
+ *
1383
+ * console.log(isEquivalent(Option.some(1), Option.some(1)))
1384
+ * // Output: true
827
1385
  * ```
828
1386
  *
829
- * @category equivalence
1387
+ * @category Equivalence
830
1388
  * @since 2.0.0
831
1389
  */
832
1390
  export const getEquivalence = isEquivalent => Equivalence.make((x, y) => isNone(x) ? isNone(y) : isNone(y) ? false : isEquivalent(x.value, y.value));
833
1391
  /**
834
- * The `Order` instance allows `Option` values to be compared with
835
- * `compare`, whenever there is an `Order` instance for
836
- * the type the `Option` contains.
1392
+ * Creates an `Order` instance for comparing `Option` values, using a provided
1393
+ * `Order` for the inner type.
837
1394
  *
838
- * `None` is considered to be less than any `Some` value.
1395
+ * **Details**
1396
+ *
1397
+ * This function produces an `Order` instance for `Option<A>`, allowing `Option`
1398
+ * values to be compared:
1399
+ *
1400
+ * - `None` is always considered less than any `Some` value.
1401
+ * - If both are `Some`, their inner values are compared using the provided
1402
+ * `Order` instance.
839
1403
  *
840
1404
  * @example
841
1405
  * ```ts
842
- * import { pipe, Option, Number } from "effect"
843
- *
844
- * const O = Option.getOrder(Number.Order)
845
- * assert.deepStrictEqual(O(Option.none(), Option.none()), 0)
846
- * assert.deepStrictEqual(O(Option.none(), Option.some(1)), -1)
847
- * assert.deepStrictEqual(O(Option.some(1), Option.none()), 1)
848
- * assert.deepStrictEqual(O(Option.some(1), Option.some(2)), -1)
849
- * assert.deepStrictEqual(O(Option.some(1), Option.some(1)), 0)
1406
+ * import { Number, Option } from "effect"
1407
+ *
1408
+ * const order = Option.getOrder(Number.Order)
1409
+ *
1410
+ * console.log(order(Option.none(), Option.none()))
1411
+ * // Output: 0
1412
+ *
1413
+ * console.log(order(Option.none(), Option.some(1)))
1414
+ * // Output: -1
1415
+ *
1416
+ * console.log(order(Option.some(1), Option.none()))
1417
+ * // Output: 1
1418
+ *
1419
+ * console.log(order(Option.some(1), Option.some(2)))
1420
+ * // Output: -1
1421
+ *
1422
+ * console.log(order(Option.some(1), Option.some(1)))
1423
+ * // Output: 0
850
1424
  * ```
851
1425
  *
852
- * @category sorting
1426
+ * @category Sorting
853
1427
  * @since 2.0.0
854
1428
  */
855
1429
  export const getOrder = O => order.make((self, that) => isSome(self) ? isSome(that) ? O(self.value, that.value) : 1 : -1);
856
1430
  /**
857
- * Lifts a binary function into `Option`.
1431
+ * Lifts a binary function to work with `Option` values, allowing the function
1432
+ * to operate on two `Option`s.
1433
+ *
1434
+ * **Details**
858
1435
  *
859
- * @param f - The function to lift.
1436
+ * This function takes a binary function `f` and returns a new function that
1437
+ * applies `f` to the values of two `Option`s (`self` and `that`). If both
1438
+ * `Option`s are `Some`, the binary function `f` is applied to their values, and
1439
+ * the result is wrapped in a new `Some`. If either `Option` is `None`, the
1440
+ * result is `None`.
860
1441
  *
861
- * @category lifting
1442
+ * @example
1443
+ * ```ts
1444
+ * import { Option } from "effect"
1445
+ *
1446
+ * // A binary function to add two numbers
1447
+ * const add = (a: number, b: number): number => a + b
1448
+ *
1449
+ * // Lift the `add` function to work with `Option` values
1450
+ * const addOptions = Option.lift2(add)
1451
+ *
1452
+ * // Both `Option`s are `Some`
1453
+ * console.log(addOptions(Option.some(2), Option.some(3)))
1454
+ * // Output: { _id: 'Option', _tag: 'Some', value: 5 }
1455
+ *
1456
+ * // One `Option` is `None`
1457
+ * console.log(addOptions(Option.some(2), Option.none()))
1458
+ * // Output: { _id: 'Option', _tag: 'None' }
1459
+ * ```
1460
+ *
1461
+ * @category Lifting
862
1462
  * @since 2.0.0
863
1463
  */
864
1464
  export const lift2 = f => dual(2, (self, that) => zipWith(self, that, f));
865
1465
  /**
866
- * Transforms a `Predicate` function into a `Some` of the input value if the predicate returns `true` or `None`
867
- * if the predicate returns `false`.
1466
+ * Lifts a `Predicate` or `Refinement` into the `Option` context, returning a
1467
+ * `Some` of the input value if the predicate is satisfied, or `None` otherwise.
868
1468
  *
869
- * @param predicate - A `Predicate` function that takes in a value of type `A` and returns a boolean.
1469
+ * **Details**
1470
+ *
1471
+ * This function transforms a `Predicate` (or a more specific `Refinement`) into
1472
+ * a function that produces an `Option`. If the predicate evaluates to `true`,
1473
+ * the input value is wrapped in a `Some`. If the predicate evaluates to
1474
+ * `false`, the result is `None`.
870
1475
  *
871
1476
  * @example
872
1477
  * ```ts
873
1478
  * import { Option } from "effect"
874
1479
  *
875
- * const getOption = Option.liftPredicate((n: number) => n >= 0)
1480
+ * // Check if a number is positive
1481
+ * const isPositive = (n: number) => n > 0
1482
+ *
1483
+ * // ┌─── (b: number) => Option<number>
1484
+ * // ▼
1485
+ * const parsePositive = Option.liftPredicate(isPositive)
876
1486
  *
877
- * assert.deepStrictEqual(getOption(-1), Option.none())
878
- * assert.deepStrictEqual(getOption(1), Option.some(1))
1487
+ * console.log(parsePositive(1))
1488
+ * // Output: { _id: 'Option', _tag: 'Some', value: 1 }
1489
+ *
1490
+ * console.log(parsePositive(-1))
1491
+ * // OUtput: { _id: 'Option', _tag: 'None' }
879
1492
  * ```
880
1493
  *
881
- * @category lifting
1494
+ * @category Lifting
882
1495
  * @since 2.0.0
883
1496
  */
884
1497
  export const liftPredicate = /*#__PURE__*/dual(2, (b, predicate) => predicate(b) ? some(b) : none());
885
1498
  /**
886
- * Returns a function that checks if a `Option` contains a given value using a provided `isEquivalent` function.
1499
+ * Returns a function that checks if an `Option` contains a specified value,
1500
+ * using a provided equivalence function.
1501
+ *
1502
+ * **Details**
887
1503
  *
888
- * @param equivalent - An `Equivalence` instance to compare values of the `Option`.
889
- * @param self - The `Option` to apply the comparison to.
890
- * @param a - The value to compare against the `Option`.
1504
+ * This function allows you to check whether an `Option` contains a specific
1505
+ * value. It uses an equivalence function `isEquivalent` to compare the value
1506
+ * inside the `Option` to the provided value. If the `Option` is `Some` and the
1507
+ * equivalence function returns `true`, the result is `true`. If the `Option` is
1508
+ * `None` or the values are not equivalent, the result is `false`.
1509
+ *
1510
+ * @see {@link contains} for a version that uses the default `Equivalence`.
891
1511
  *
892
1512
  * @example
893
1513
  * ```ts
894
- * import { pipe, Option, Number } from "effect"
1514
+ * import { Number, Option } from "effect"
1515
+ *
1516
+ * const contains = Option.containsWith(Number.Equivalence)
1517
+ *
1518
+ * console.log(Option.some(2).pipe(contains(2)))
1519
+ * // Output: true
1520
+ *
1521
+ * console.log(Option.some(1).pipe(contains(2)))
1522
+ * // Output: false
895
1523
  *
896
- * assert.deepStrictEqual(pipe(Option.some(2), Option.containsWith(Number.Equivalence)(2)), true)
897
- * assert.deepStrictEqual(pipe(Option.some(1), Option.containsWith(Number.Equivalence)(2)), false)
898
- * assert.deepStrictEqual(pipe(Option.none(), Option.containsWith(Number.Equivalence)(2)), false)
1524
+ * console.log(Option.none().pipe(contains(2)))
1525
+ * // Output: false
899
1526
  * ```
900
1527
  *
901
- * @category elements
1528
+ * @category Elements
902
1529
  * @since 2.0.0
903
1530
  */
904
1531
  export const containsWith = isEquivalent => dual(2, (self, a) => isNone(self) ? false : isEquivalent(self.value, a));
905
1532
  const _equivalence = /*#__PURE__*/Equal.equivalence();
906
1533
  /**
907
- * Returns a function that checks if an `Option` contains a given value using the default `Equivalence`.
1534
+ * Returns a function that checks if an `Option` contains a specified value
1535
+ * using the default `Equivalence`.
908
1536
  *
909
- * @category elements
1537
+ * **Details**
1538
+ *
1539
+ * This function allows you to check whether an `Option` contains a specific
1540
+ * value. It uses the default `Equivalence` for equality comparison. If the
1541
+ * `Option` is `Some` and its value is equivalent to the provided value, the
1542
+ * result is `true`. If the `Option` is `None` or the values are not equivalent,
1543
+ * the result is `false`.
1544
+ *
1545
+ * @see {@link containsWith} for a version that allows you to specify a custom equivalence function.
1546
+ *
1547
+ * @example
1548
+ * ```ts
1549
+ * import { Option } from "effect"
1550
+ *
1551
+ * console.log(Option.some(2).pipe(Option.contains(2)))
1552
+ * // Output: true
1553
+ *
1554
+ * console.log(Option.some(1).pipe(Option.contains(2)))
1555
+ * // Output: false
1556
+ *
1557
+ * console.log(Option.none().pipe(Option.contains(2)))
1558
+ * // Output: false
1559
+ * ```
1560
+ *
1561
+ * @category Elements
910
1562
  * @since 2.0.0
911
1563
  */
912
1564
  export const contains = /*#__PURE__*/containsWith(_equivalence);
913
1565
  /**
914
- * Check if a value in an `Option` type meets a certain predicate.
1566
+ * Checks if a value in an `Option` satisfies a given predicate or refinement.
1567
+ *
1568
+ * **Details**
1569
+ *
1570
+ * This function allows you to check if a value inside a `Some` meets a
1571
+ * specified condition. If the `Option` is `None`, the result is `false`. If the
1572
+ * `Option` is `Some`, the provided predicate or refinement is applied to the
1573
+ * value:
915
1574
  *
916
- * @param self - The `Option` to check.
917
- * @param predicate - The condition to check.
1575
+ * - If the condition is met, the result is `true`.
1576
+ * - If the condition is not met, the result is `false`.
918
1577
  *
919
1578
  * @example
920
1579
  * ```ts
921
- * import { pipe, Option } from "effect"
1580
+ * import { Option } from "effect"
922
1581
  *
923
1582
  * const isEven = (n: number) => n % 2 === 0
924
1583
  *
925
- * assert.deepStrictEqual(pipe(Option.some(2), Option.exists(isEven)), true)
926
- * assert.deepStrictEqual(pipe(Option.some(1), Option.exists(isEven)), false)
927
- * assert.deepStrictEqual(pipe(Option.none(), Option.exists(isEven)), false)
1584
+ * console.log(Option.some(2).pipe(Option.exists(isEven)))
1585
+ * // Output: true
1586
+ *
1587
+ * console.log(Option.some(1).pipe(Option.exists(isEven)))
1588
+ * // Output: false
1589
+ *
1590
+ * console.log(Option.none().pipe(Option.exists(isEven)))
1591
+ * // Output: false
928
1592
  * ```
929
1593
  *
1594
+ * @category Elements
930
1595
  * @since 2.0.0
931
1596
  */
932
1597
  export const exists = /*#__PURE__*/dual(2, (self, refinement) => isNone(self) ? false : refinement(self.value));
@@ -962,7 +1627,7 @@ export const exists = /*#__PURE__*/dual(2, (self, refinement) => isNone(self) ?
962
1627
  * assert.deepStrictEqual(result, Option.some({ x: 2, y: 3, sum: 5 }))
963
1628
  * ```
964
1629
  *
965
- * @category do notation
1630
+ * @category Do notation
966
1631
  * @since 2.0.0
967
1632
  */
968
1633
  export const bindTo = /*#__PURE__*/doNotation.bindTo(map);
@@ -997,7 +1662,7 @@ export {
997
1662
  * assert.deepStrictEqual(result, Option.some({ x: 2, y: 3, sum: 5 }))
998
1663
  *
999
1664
  * ```
1000
- * @category do notation
1665
+ * @category Do notation
1001
1666
  * @since 2.0.0
1002
1667
  */
1003
1668
  let_ as let };
@@ -1030,7 +1695,7 @@ let_ as let };
1030
1695
  * assert.deepStrictEqual(result, Option.some({ x: 2, y: 3, sum: 5 }))
1031
1696
  * ```
1032
1697
  *
1033
- * @category do notation
1698
+ * @category Do notation
1034
1699
  * @since 2.0.0
1035
1700
  */
1036
1701
  export const bind = /*#__PURE__*/doNotation.bind(map, flatMap);
@@ -1063,51 +1728,64 @@ export const bind = /*#__PURE__*/doNotation.bind(map, flatMap);
1063
1728
  * assert.deepStrictEqual(result, Option.some({ x: 2, y: 3, sum: 5 }))
1064
1729
  * ```
1065
1730
  *
1066
- * @category do notation
1731
+ * @category Do notation
1067
1732
  * @since 2.0.0
1068
1733
  */
1069
1734
  export const Do = /*#__PURE__*/some({});
1070
1735
  const adapter = /*#__PURE__*/Gen.adapter();
1071
1736
  /**
1072
- * @category generators
1737
+ * Similar to `Effect.gen`, `Option.gen` provides a more readable,
1738
+ * generator-based syntax for working with `Option` values, making code that
1739
+ * involves `Option` easier to write and understand. This approach is similar to
1740
+ * using `async/await` but tailored for `Option`.
1741
+ *
1742
+ * @example
1743
+ * ```ts
1744
+ * // Title: Using Option.gen to Create a Combined Value
1745
+ * import { Option } from "effect"
1746
+ *
1747
+ * const maybeName: Option.Option<string> = Option.some("John")
1748
+ * const maybeAge: Option.Option<number> = Option.some(25)
1749
+ *
1750
+ * const person = Option.gen(function* () {
1751
+ * const name = (yield* maybeName).toUpperCase()
1752
+ * const age = yield* maybeAge
1753
+ * return { name, age }
1754
+ * })
1755
+ *
1756
+ * console.log(person)
1757
+ * // Output:
1758
+ * // { _id: 'Option', _tag: 'Some', value: { name: 'JOHN', age: 25 } }
1759
+ * ```
1760
+ *
1761
+ * @category Generators
1073
1762
  * @since 2.0.0
1074
1763
  */
1075
1764
  export const gen = (...args) => {
1076
- let f;
1077
- if (args.length === 1) {
1078
- f = args[0];
1079
- } else {
1080
- f = args[1].bind(args[0]);
1081
- }
1765
+ const f = args.length === 1 ? args[0] : args[1].bind(args[0]);
1082
1766
  const iterator = f(adapter);
1083
1767
  let state = iterator.next();
1084
- if (state.done) {
1085
- return some(state.value);
1086
- } else {
1087
- let current = state.value;
1088
- if (Gen.isGenKind(current)) {
1089
- current = current.value;
1090
- } else {
1091
- current = Gen.yieldWrapGet(current);
1092
- }
1768
+ while (!state.done) {
1769
+ const current = Gen.isGenKind(state.value) ? state.value.value : Gen.yieldWrapGet(state.value);
1093
1770
  if (isNone(current)) {
1094
1771
  return current;
1095
1772
  }
1096
- while (!state.done) {
1097
- state = iterator.next(current.value);
1098
- if (!state.done) {
1099
- current = state.value;
1100
- if (Gen.isGenKind(current)) {
1101
- current = current.value;
1102
- } else {
1103
- current = Gen.yieldWrapGet(current);
1104
- }
1105
- if (isNone(current)) {
1106
- return current;
1107
- }
1108
- }
1109
- }
1110
- return some(state.value);
1773
+ state = iterator.next(current.value);
1774
+ }
1775
+ return some(state.value);
1776
+ };
1777
+ /**
1778
+ * Merges two optional values, applying a function if both exist.
1779
+ * Unlike {@link zipWith}, this function returns `None` only if both inputs are `None`.
1780
+ *
1781
+ * @internal
1782
+ */
1783
+ export const mergeWith = f => (o1, o2) => {
1784
+ if (isNone(o1)) {
1785
+ return o2;
1786
+ } else if (isNone(o2)) {
1787
+ return o1;
1111
1788
  }
1789
+ return some(f(o1.value, o2.value));
1112
1790
  };
1113
1791
  //# sourceMappingURL=Option.js.map