effect 3.12.11 → 3.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -49
- package/dist/cjs/Channel.js.map +1 -1
- package/dist/cjs/DateTime.js +17 -1
- package/dist/cjs/DateTime.js.map +1 -1
- package/dist/cjs/Differ.js.map +1 -1
- package/dist/cjs/Duration.js +128 -1
- package/dist/cjs/Duration.js.map +1 -1
- package/dist/cjs/Effect.js +175 -37
- package/dist/cjs/Effect.js.map +1 -1
- package/dist/cjs/Either.js +2 -1
- package/dist/cjs/Either.js.map +1 -1
- package/dist/cjs/FiberHandle.js +54 -21
- package/dist/cjs/FiberHandle.js.map +1 -1
- package/dist/cjs/FiberMap.js +51 -24
- package/dist/cjs/FiberMap.js.map +1 -1
- package/dist/cjs/FiberSet.js +50 -17
- package/dist/cjs/FiberSet.js.map +1 -1
- package/dist/cjs/HashMap.js +19 -1
- package/dist/cjs/HashMap.js.map +1 -1
- package/dist/cjs/HashSet.js +9 -1
- package/dist/cjs/HashSet.js.map +1 -1
- package/dist/cjs/Layer.js +21 -1
- package/dist/cjs/Layer.js.map +1 -1
- package/dist/cjs/Match.js +659 -38
- package/dist/cjs/Match.js.map +1 -1
- package/dist/cjs/RcMap.js +11 -1
- package/dist/cjs/RcMap.js.map +1 -1
- package/dist/cjs/Reloadable.js.map +1 -1
- package/dist/cjs/STM.js.map +1 -1
- package/dist/cjs/Schedule.js +1074 -309
- package/dist/cjs/Schedule.js.map +1 -1
- package/dist/cjs/Schema.js +73 -1
- package/dist/cjs/Schema.js.map +1 -1
- package/dist/cjs/Stream.js.map +1 -1
- package/dist/cjs/internal/channel.js.map +1 -1
- package/dist/cjs/internal/core-effect.js.map +1 -1
- package/dist/cjs/internal/core.js +27 -3
- package/dist/cjs/internal/core.js.map +1 -1
- package/dist/cjs/internal/dateTime.js +4 -1
- package/dist/cjs/internal/dateTime.js.map +1 -1
- package/dist/cjs/internal/differ.js +4 -0
- package/dist/cjs/internal/differ.js.map +1 -1
- package/dist/cjs/internal/effect/circular.js +3 -2
- package/dist/cjs/internal/effect/circular.js.map +1 -1
- package/dist/cjs/internal/fiberRuntime.js +21 -7
- package/dist/cjs/internal/fiberRuntime.js.map +1 -1
- package/dist/cjs/internal/hashMap.js +10 -1
- package/dist/cjs/internal/hashMap.js.map +1 -1
- package/dist/cjs/internal/keyedPool.js +1 -1
- package/dist/cjs/internal/keyedPool.js.map +1 -1
- package/dist/cjs/internal/layer.js.map +1 -1
- package/dist/cjs/internal/rcMap.js +86 -56
- package/dist/cjs/internal/rcMap.js.map +1 -1
- package/dist/cjs/internal/reloadable.js.map +1 -1
- package/dist/cjs/internal/schedule.js.map +1 -1
- package/dist/cjs/internal/sink.js.map +1 -1
- package/dist/cjs/internal/stm/stm.js.map +1 -1
- package/dist/cjs/internal/stream.js.map +1 -1
- package/dist/cjs/internal/version.js +1 -1
- package/dist/cjs/internal/version.js.map +1 -1
- package/dist/dts/Channel.d.ts +4 -4
- package/dist/dts/Channel.d.ts.map +1 -1
- package/dist/dts/DateTime.d.ts +16 -0
- package/dist/dts/DateTime.d.ts.map +1 -1
- package/dist/dts/Differ.d.ts +2 -1
- package/dist/dts/Differ.d.ts.map +1 -1
- package/dist/dts/Duration.d.ts +64 -0
- package/dist/dts/Duration.d.ts.map +1 -1
- package/dist/dts/Effect.d.ts +402 -30
- package/dist/dts/Effect.d.ts.map +1 -1
- package/dist/dts/Either.d.ts +7 -0
- package/dist/dts/Either.d.ts.map +1 -1
- package/dist/dts/FiberHandle.d.ts +26 -0
- package/dist/dts/FiberHandle.d.ts.map +1 -1
- package/dist/dts/FiberMap.d.ts +26 -0
- package/dist/dts/FiberMap.d.ts.map +1 -1
- package/dist/dts/FiberSet.d.ts +25 -0
- package/dist/dts/FiberSet.d.ts.map +1 -1
- package/dist/dts/HashMap.d.ts +38 -0
- package/dist/dts/HashMap.d.ts.map +1 -1
- package/dist/dts/HashSet.d.ts +7 -0
- package/dist/dts/HashSet.d.ts.map +1 -1
- package/dist/dts/Layer.d.ts +32 -13
- package/dist/dts/Layer.d.ts.map +1 -1
- package/dist/dts/Match.d.ts +731 -48
- package/dist/dts/Match.d.ts.map +1 -1
- package/dist/dts/RcMap.d.ts +32 -0
- package/dist/dts/RcMap.d.ts.map +1 -1
- package/dist/dts/Reloadable.d.ts +13 -13
- package/dist/dts/Reloadable.d.ts.map +1 -1
- package/dist/dts/STM.d.ts +4 -4
- package/dist/dts/STM.d.ts.map +1 -1
- package/dist/dts/Schedule.d.ts +2294 -633
- package/dist/dts/Schedule.d.ts.map +1 -1
- package/dist/dts/Schema.d.ts +40 -4
- package/dist/dts/Schema.d.ts.map +1 -1
- package/dist/dts/Stream.d.ts +8 -8
- package/dist/dts/Stream.d.ts.map +1 -1
- package/dist/dts/Trie.d.ts +7 -7
- package/dist/dts/Trie.d.ts.map +1 -1
- package/dist/dts/index.d.ts +25 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/internal/stm/stm.d.ts +2 -2
- package/dist/dts/internal/stm/stm.d.ts.map +1 -1
- package/dist/esm/Channel.js.map +1 -1
- package/dist/esm/DateTime.js +16 -0
- package/dist/esm/DateTime.js.map +1 -1
- package/dist/esm/Differ.js.map +1 -1
- package/dist/esm/Duration.js +124 -0
- package/dist/esm/Duration.js.map +1 -1
- package/dist/esm/Effect.js +170 -32
- package/dist/esm/Effect.js.map +1 -1
- package/dist/esm/Either.js +7 -0
- package/dist/esm/Either.js.map +1 -1
- package/dist/esm/FiberHandle.js +48 -18
- package/dist/esm/FiberHandle.js.map +1 -1
- package/dist/esm/FiberMap.js +46 -22
- package/dist/esm/FiberMap.js.map +1 -1
- package/dist/esm/FiberSet.js +45 -15
- package/dist/esm/FiberSet.js.map +1 -1
- package/dist/esm/HashMap.js +17 -0
- package/dist/esm/HashMap.js.map +1 -1
- package/dist/esm/HashSet.js +7 -0
- package/dist/esm/HashSet.js.map +1 -1
- package/dist/esm/Layer.js +20 -0
- package/dist/esm/Layer.js.map +1 -1
- package/dist/esm/Match.js +665 -40
- package/dist/esm/Match.js.map +1 -1
- package/dist/esm/RcMap.js +10 -0
- package/dist/esm/RcMap.js.map +1 -1
- package/dist/esm/Reloadable.js.map +1 -1
- package/dist/esm/STM.js.map +1 -1
- package/dist/esm/Schedule.js +1074 -309
- package/dist/esm/Schedule.js.map +1 -1
- package/dist/esm/Schema.js +71 -0
- package/dist/esm/Schema.js.map +1 -1
- package/dist/esm/Stream.js.map +1 -1
- package/dist/esm/index.js +25 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal/channel.js.map +1 -1
- package/dist/esm/internal/core-effect.js.map +1 -1
- package/dist/esm/internal/core.js +23 -0
- package/dist/esm/internal/core.js.map +1 -1
- package/dist/esm/internal/dateTime.js +2 -0
- package/dist/esm/internal/dateTime.js.map +1 -1
- package/dist/esm/internal/differ.js +4 -0
- package/dist/esm/internal/differ.js.map +1 -1
- package/dist/esm/internal/effect/circular.js +3 -2
- package/dist/esm/internal/effect/circular.js.map +1 -1
- package/dist/esm/internal/fiberRuntime.js +18 -5
- package/dist/esm/internal/fiberRuntime.js.map +1 -1
- package/dist/esm/internal/hashMap.js +9 -0
- package/dist/esm/internal/hashMap.js.map +1 -1
- package/dist/esm/internal/keyedPool.js +1 -1
- package/dist/esm/internal/keyedPool.js.map +1 -1
- package/dist/esm/internal/layer.js.map +1 -1
- package/dist/esm/internal/rcMap.js +85 -55
- package/dist/esm/internal/rcMap.js.map +1 -1
- package/dist/esm/internal/reloadable.js.map +1 -1
- package/dist/esm/internal/schedule.js.map +1 -1
- package/dist/esm/internal/sink.js.map +1 -1
- package/dist/esm/internal/stm/stm.js.map +1 -1
- package/dist/esm/internal/stream.js.map +1 -1
- package/dist/esm/internal/version.js +1 -1
- package/dist/esm/internal/version.js.map +1 -1
- package/package.json +2 -1
- package/src/Channel.ts +14 -17
- package/src/DateTime.ts +17 -8
- package/src/Differ.ts +2 -1
- package/src/Duration.ts +147 -0
- package/src/Effect.ts +528 -140
- package/src/Either.ts +9 -0
- package/src/FiberHandle.ts +95 -35
- package/src/FiberMap.ts +104 -39
- package/src/FiberSet.ts +93 -24
- package/src/HashMap.ts +40 -0
- package/src/HashSet.ts +8 -0
- package/src/Layer.ts +94 -40
- package/src/Match.ts +733 -49
- package/src/RcMap.ts +34 -0
- package/src/Reloadable.ts +17 -27
- package/src/STM.ts +10 -17
- package/src/Schedule.ts +2325 -653
- package/src/Schema.ts +81 -4
- package/src/Stream.ts +26 -33
- package/src/Trie.ts +7 -7
- package/src/index.ts +25 -0
- package/src/internal/channel.ts +37 -39
- package/src/internal/core-effect.ts +84 -84
- package/src/internal/core.ts +80 -0
- package/src/internal/dateTime.ts +3 -0
- package/src/internal/differ.ts +4 -0
- package/src/internal/effect/circular.ts +3 -2
- package/src/internal/fiberRuntime.ts +31 -6
- package/src/internal/hashMap.ts +16 -0
- package/src/internal/keyedPool.ts +1 -1
- package/src/internal/layer.ts +52 -52
- package/src/internal/rcMap.ts +131 -89
- package/src/internal/reloadable.ts +25 -28
- package/src/internal/schedule.ts +29 -23
- package/src/internal/sink.ts +16 -15
- package/src/internal/stm/stm.ts +54 -46
- package/src/internal/stream.ts +100 -100
- package/src/internal/version.ts +1 -1
package/dist/esm/Match.js
CHANGED
|
@@ -1,202 +1,827 @@
|
|
|
1
1
|
import * as internal from "./internal/matcher.js";
|
|
2
2
|
import * as Predicate from "./Predicate.js";
|
|
3
3
|
/**
|
|
4
|
-
* @category
|
|
4
|
+
* @category Symbols
|
|
5
5
|
* @since 1.0.0
|
|
6
6
|
*/
|
|
7
7
|
export const MatcherTypeId = internal.TypeId;
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* Creates a matcher for a specific type.
|
|
10
|
+
*
|
|
11
|
+
* **Details**
|
|
12
|
+
*
|
|
13
|
+
* This function defines a `Matcher` that operates on a given type, allowing you
|
|
14
|
+
* to specify conditions for handling different cases. Once the matcher is
|
|
15
|
+
* created, you can use pattern-matching functions like {@link when} to define
|
|
16
|
+
* how different values should be processed.
|
|
17
|
+
*
|
|
18
|
+
* @see {@link value} for creating a matcher from a specific value.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* // Title: Matching Numbers and Strings
|
|
23
|
+
* import { Match } from "effect"
|
|
24
|
+
*
|
|
25
|
+
* // Create a matcher for values that are either strings or numbers
|
|
26
|
+
* //
|
|
27
|
+
* // ┌─── (u: string | number) => string
|
|
28
|
+
* // ▼
|
|
29
|
+
* const match = Match.type<string | number>().pipe(
|
|
30
|
+
* // Match when the value is a number
|
|
31
|
+
* Match.when(Match.number, (n) => `number: ${n}`),
|
|
32
|
+
* // Match when the value is a string
|
|
33
|
+
* Match.when(Match.string, (s) => `string: ${s}`),
|
|
34
|
+
* // Ensure all possible cases are handled
|
|
35
|
+
* Match.exhaustive
|
|
36
|
+
* )
|
|
37
|
+
*
|
|
38
|
+
* console.log(match(0))
|
|
39
|
+
* // Output: "number: 0"
|
|
40
|
+
*
|
|
41
|
+
* console.log(match("hello"))
|
|
42
|
+
* // Output: "string: hello"
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* @category Creating a matcher
|
|
10
46
|
* @since 1.0.0
|
|
11
47
|
*/
|
|
12
48
|
export const type = internal.type;
|
|
13
49
|
/**
|
|
14
|
-
*
|
|
50
|
+
* Creates a matcher from a specific value.
|
|
51
|
+
*
|
|
52
|
+
* **Details**
|
|
53
|
+
*
|
|
54
|
+
* This function allows you to define a `Matcher` directly from a given value,
|
|
55
|
+
* rather than from a type. This is useful when working with known values,
|
|
56
|
+
* enabling structured pattern matching on objects, primitives, or any data
|
|
57
|
+
* structure.
|
|
58
|
+
*
|
|
59
|
+
* Once the matcher is created, you can use pattern-matching functions like
|
|
60
|
+
* {@link when} to define how different cases should be handled.
|
|
61
|
+
*
|
|
62
|
+
* @see {@link type} for creating a matcher from a specific type.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* // Title: Matching an Object by Property
|
|
67
|
+
* import { Match } from "effect"
|
|
68
|
+
*
|
|
69
|
+
* const input = { name: "John", age: 30 }
|
|
70
|
+
*
|
|
71
|
+
* // Create a matcher for the specific object
|
|
72
|
+
* const result = Match.value(input).pipe(
|
|
73
|
+
* // Match when the 'name' property is "John"
|
|
74
|
+
* Match.when(
|
|
75
|
+
* { name: "John" },
|
|
76
|
+
* (user) => `${user.name} is ${user.age} years old`
|
|
77
|
+
* ),
|
|
78
|
+
* // Provide a fallback if no match is found
|
|
79
|
+
* Match.orElse(() => "Oh, not John")
|
|
80
|
+
* )
|
|
81
|
+
*
|
|
82
|
+
* console.log(result)
|
|
83
|
+
* // Output: "John is 30 years old"
|
|
84
|
+
* ```
|
|
85
|
+
*
|
|
86
|
+
* @category Creating a matcher
|
|
15
87
|
* @since 1.0.0
|
|
16
88
|
*/
|
|
17
89
|
export const value = internal.value;
|
|
18
90
|
/**
|
|
19
|
-
* @category
|
|
91
|
+
* @category Creating a matcher
|
|
20
92
|
* @since 1.0.0
|
|
21
93
|
*/
|
|
22
94
|
export const valueTags = internal.valueTags;
|
|
23
95
|
/**
|
|
24
|
-
* @category
|
|
96
|
+
* @category Creating a matcher
|
|
25
97
|
* @since 1.0.0
|
|
26
98
|
*/
|
|
27
99
|
export const typeTags = internal.typeTags;
|
|
28
100
|
/**
|
|
29
|
-
*
|
|
101
|
+
* Ensures that all branches of a matcher return a specific type.
|
|
102
|
+
*
|
|
103
|
+
* **Details**
|
|
104
|
+
*
|
|
105
|
+
* This function enforces a consistent return type across all pattern-matching
|
|
106
|
+
* branches. By specifying a return type, TypeScript will check that every
|
|
107
|
+
* matching condition produces a value of the expected type.
|
|
108
|
+
*
|
|
109
|
+
* **Important:** This function must be the first step in the matcher pipeline.
|
|
110
|
+
* If used later, TypeScript will not enforce type consistency correctly.
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* ```ts
|
|
114
|
+
* // Title: Validating Return Type Consistency
|
|
115
|
+
* import { Match } from "effect"
|
|
116
|
+
*
|
|
117
|
+
* const match = Match.type<{ a: number } | { b: string }>().pipe(
|
|
118
|
+
* // Ensure all branches return a string
|
|
119
|
+
* Match.withReturnType<string>(),
|
|
120
|
+
* // ❌ Type error: 'number' is not assignable to type 'string'
|
|
121
|
+
* // @ts-expect-error
|
|
122
|
+
* Match.when({ a: Match.number }, (_) => _.a),
|
|
123
|
+
* // ✅ Correct: returns a string
|
|
124
|
+
* Match.when({ b: Match.string }, (_) => _.b),
|
|
125
|
+
* Match.exhaustive
|
|
126
|
+
* )
|
|
127
|
+
* ```
|
|
128
|
+
*
|
|
30
129
|
* @since 1.0.0
|
|
31
130
|
*/
|
|
32
131
|
export const withReturnType = internal.withReturnType;
|
|
33
132
|
/**
|
|
34
|
-
*
|
|
133
|
+
* Defines a condition for matching values.
|
|
134
|
+
*
|
|
135
|
+
* **Details**
|
|
136
|
+
*
|
|
137
|
+
* This function enables pattern matching by checking whether a given value
|
|
138
|
+
* satisfies a condition. It supports both direct value comparisons and
|
|
139
|
+
* predicate functions. If the condition is met, the associated function is
|
|
140
|
+
* executed.
|
|
141
|
+
*
|
|
142
|
+
* This function is useful when defining matchers that need to check for
|
|
143
|
+
* specific values or apply logical conditions to determine a match. It works
|
|
144
|
+
* well with structured objects and primitive types.
|
|
145
|
+
*
|
|
146
|
+
* @see {@link whenOr} Use this when multiple patterns should match in a single
|
|
147
|
+
* condition.
|
|
148
|
+
* @see {@link whenAnd} Use this when a value must match all provided patterns.
|
|
149
|
+
* @see {@link orElse} Provides a fallback when no patterns match.
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```ts
|
|
153
|
+
* // Title: Matching with Values and Predicates
|
|
154
|
+
* import { Match } from "effect"
|
|
155
|
+
*
|
|
156
|
+
* // Create a matcher for objects with an "age" property
|
|
157
|
+
* const match = Match.type<{ age: number }>().pipe(
|
|
158
|
+
* // Match when age is greater than 18
|
|
159
|
+
* Match.when({ age: (age) => age > 18 }, (user) => `Age: ${user.age}`),
|
|
160
|
+
* // Match when age is exactly 18
|
|
161
|
+
* Match.when({ age: 18 }, () => "You can vote"),
|
|
162
|
+
* // Fallback case for all other ages
|
|
163
|
+
* Match.orElse((user) => `${user.age} is too young`)
|
|
164
|
+
* )
|
|
165
|
+
*
|
|
166
|
+
* console.log(match({ age: 20 }))
|
|
167
|
+
* // Output: "Age: 20"
|
|
168
|
+
*
|
|
169
|
+
* console.log(match({ age: 18 }))
|
|
170
|
+
* // Output: "You can vote"
|
|
171
|
+
*
|
|
172
|
+
* console.log(match({ age: 4 }))
|
|
173
|
+
* // Output: "4 is too young"
|
|
174
|
+
* ```
|
|
175
|
+
*
|
|
176
|
+
* @category Defining patterns
|
|
35
177
|
* @since 1.0.0
|
|
36
178
|
*/
|
|
37
179
|
export const when = internal.when;
|
|
38
180
|
/**
|
|
39
|
-
*
|
|
181
|
+
* Matches one of multiple patterns in a single condition.
|
|
182
|
+
*
|
|
183
|
+
* **Details**
|
|
184
|
+
*
|
|
185
|
+
* This function allows defining a condition where a value matches any of the
|
|
186
|
+
* provided patterns. If a match is found, the associated function is executed.
|
|
187
|
+
* It simplifies cases where multiple patterns share the same handling logic.
|
|
188
|
+
*
|
|
189
|
+
* Unlike {@link when}, which requires separate conditions for each pattern,
|
|
190
|
+
* this function enables combining them into a single statement, making the
|
|
191
|
+
* matcher more concise.
|
|
192
|
+
*
|
|
193
|
+
* @example
|
|
194
|
+
* ```ts
|
|
195
|
+
* import { Match } from "effect"
|
|
196
|
+
*
|
|
197
|
+
* type ErrorType =
|
|
198
|
+
* | { readonly _tag: "NetworkError"; readonly message: string }
|
|
199
|
+
* | { readonly _tag: "TimeoutError"; readonly duration: number }
|
|
200
|
+
* | { readonly _tag: "ValidationError"; readonly field: string }
|
|
201
|
+
*
|
|
202
|
+
* const handleError = Match.type<ErrorType>().pipe(
|
|
203
|
+
* Match.whenOr(
|
|
204
|
+
* { _tag: "NetworkError" },
|
|
205
|
+
* { _tag: "TimeoutError" },
|
|
206
|
+
* () => "Retry the request"
|
|
207
|
+
* ),
|
|
208
|
+
* Match.when({ _tag: "ValidationError" }, (_) => `Invalid field: ${_.field}`),
|
|
209
|
+
* Match.exhaustive
|
|
210
|
+
* )
|
|
211
|
+
*
|
|
212
|
+
* console.log(handleError({ _tag: "NetworkError", message: "No connection" }))
|
|
213
|
+
* // Output: "Retry the request"
|
|
214
|
+
*
|
|
215
|
+
* console.log(handleError({ _tag: "ValidationError", field: "email" }))
|
|
216
|
+
* // Output: "Invalid field: email"
|
|
217
|
+
* ```
|
|
218
|
+
*
|
|
219
|
+
* @category Defining patterns
|
|
40
220
|
* @since 1.0.0
|
|
41
221
|
*/
|
|
42
222
|
export const whenOr = internal.whenOr;
|
|
43
223
|
/**
|
|
44
|
-
*
|
|
224
|
+
* Matches a value that satisfies all provided patterns.
|
|
225
|
+
*
|
|
226
|
+
* **Details**
|
|
227
|
+
*
|
|
228
|
+
* This function allows defining a condition where a value must match all the
|
|
229
|
+
* given patterns simultaneously. If the value satisfies every pattern, the
|
|
230
|
+
* associated function is executed.
|
|
231
|
+
*
|
|
232
|
+
* Unlike {@link when}, which matches a single pattern at a time, this function
|
|
233
|
+
* ensures that multiple conditions are met before executing the callback. It is
|
|
234
|
+
* useful when checking for values that need to fulfill multiple criteria at
|
|
235
|
+
* once.
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* ```ts
|
|
239
|
+
* import { Match } from "effect"
|
|
240
|
+
*
|
|
241
|
+
* type User = { readonly age: number; readonly role: "admin" | "user" }
|
|
242
|
+
*
|
|
243
|
+
* const checkUser = Match.type<User>().pipe(
|
|
244
|
+
* Match.whenAnd(
|
|
245
|
+
* { age: (n) => n >= 18 },
|
|
246
|
+
* { role: "admin" },
|
|
247
|
+
* () => "Admin access granted"
|
|
248
|
+
* ),
|
|
249
|
+
* Match.orElse(() => "Access denied")
|
|
250
|
+
* )
|
|
251
|
+
*
|
|
252
|
+
* console.log(checkUser({ age: 20, role: "admin" }))
|
|
253
|
+
* // Output: "Admin access granted"
|
|
254
|
+
*
|
|
255
|
+
* console.log(checkUser({ age: 20, role: "user" }))
|
|
256
|
+
* // Output: "Access denied"
|
|
257
|
+
* ```
|
|
258
|
+
*
|
|
259
|
+
* @category Defining patterns
|
|
45
260
|
* @since 1.0.0
|
|
46
261
|
*/
|
|
47
262
|
export const whenAnd = internal.whenAnd;
|
|
48
263
|
/**
|
|
49
|
-
*
|
|
264
|
+
* Matches values based on a specified discriminant field.
|
|
265
|
+
*
|
|
266
|
+
* **Details**
|
|
267
|
+
*
|
|
268
|
+
* This function is used to define pattern matching on objects that follow a
|
|
269
|
+
* **discriminated union** structure, where a specific field (e.g., `type`,
|
|
270
|
+
* `kind`, `_tag`) determines the variant of the object. It allows matching
|
|
271
|
+
* multiple values of the discriminant and provides a function to handle the
|
|
272
|
+
* matched cases.
|
|
273
|
+
*
|
|
274
|
+
* @example
|
|
275
|
+
* ```ts
|
|
276
|
+
* import { Match, pipe } from "effect"
|
|
277
|
+
*
|
|
278
|
+
* const match = pipe(
|
|
279
|
+
* Match.type<{ type: "A"; a: string } | { type: "B"; b: number } | { type: "C"; c: boolean }>(),
|
|
280
|
+
* Match.discriminator("type")("A", "B", (_) => `A or B: ${_.type}`),
|
|
281
|
+
* Match.discriminator("type")("C", (_) => `C(${_.c})`),
|
|
282
|
+
* Match.exhaustive
|
|
283
|
+
* )
|
|
284
|
+
* ```
|
|
285
|
+
*
|
|
286
|
+
* @category Defining patterns
|
|
50
287
|
* @since 1.0.0
|
|
51
288
|
*/
|
|
52
289
|
export const discriminator = internal.discriminator;
|
|
53
290
|
/**
|
|
54
|
-
*
|
|
291
|
+
* Matches values where a specified field starts with a given prefix.
|
|
292
|
+
*
|
|
293
|
+
* **Details**
|
|
294
|
+
*
|
|
295
|
+
* This function is useful for working with discriminated unions where the
|
|
296
|
+
* discriminant field follows a hierarchical or namespaced structure. It allows
|
|
297
|
+
* you to match values based on whether the specified field starts with a given
|
|
298
|
+
* prefix, making it easier to handle grouped cases.
|
|
299
|
+
*
|
|
300
|
+
* Instead of checking for exact matches, this function lets you match values
|
|
301
|
+
* that share a common prefix. For example, if your discriminant field contains
|
|
302
|
+
* hierarchical names like `"A"`, `"A.A"`, and `"B"`, you can match all values
|
|
303
|
+
* starting with `"A"` using a single rule.
|
|
304
|
+
*
|
|
305
|
+
* @example
|
|
306
|
+
* ```ts
|
|
307
|
+
* import { Match, pipe } from "effect"
|
|
308
|
+
*
|
|
309
|
+
* const match = pipe(
|
|
310
|
+
* Match.type<{ type: "A" } | { type: "B" } | { type: "A.A" } | {}>(),
|
|
311
|
+
* Match.discriminatorStartsWith("type")("A", (_) => 1 as const),
|
|
312
|
+
* Match.discriminatorStartsWith("type")("B", (_) => 2 as const),
|
|
313
|
+
* Match.orElse((_) => 3 as const)
|
|
314
|
+
* )
|
|
315
|
+
*
|
|
316
|
+
* console.log(match({ type: "A" })) // 1
|
|
317
|
+
* console.log(match({ type: "B" })) // 2
|
|
318
|
+
* console.log(match({ type: "A.A" })) // 1
|
|
319
|
+
* ```
|
|
320
|
+
*
|
|
321
|
+
* @category Defining patterns
|
|
55
322
|
* @since 1.0.0
|
|
56
323
|
*/
|
|
57
324
|
export const discriminatorStartsWith = internal.discriminatorStartsWith;
|
|
58
325
|
/**
|
|
59
|
-
*
|
|
326
|
+
* Matches values based on a field that serves as a discriminator, mapping each
|
|
327
|
+
* possible value to a corresponding handler.
|
|
328
|
+
*
|
|
329
|
+
* **Details**
|
|
330
|
+
*
|
|
331
|
+
* This function simplifies working with discriminated unions by letting you
|
|
332
|
+
* define a set of handlers for each possible value of a given field. Instead of
|
|
333
|
+
* chaining multiple calls to {@link discriminator}, this function allows
|
|
334
|
+
* defining all possible cases at once using an object where the keys are the
|
|
335
|
+
* possible values of the field, and the values are the corresponding handler
|
|
336
|
+
* functions.
|
|
337
|
+
*
|
|
338
|
+
* @example
|
|
339
|
+
* ```ts
|
|
340
|
+
* import { Match, pipe } from "effect"
|
|
341
|
+
*
|
|
342
|
+
* const match = pipe(
|
|
343
|
+
* Match.type<{ type: "A"; a: string } | { type: "B"; b: number } | { type: "C"; c: boolean }>(),
|
|
344
|
+
* Match.discriminators("type")({
|
|
345
|
+
* A: (a) => a.a,
|
|
346
|
+
* B: (b) => b.b,
|
|
347
|
+
* C: (c) => c.c
|
|
348
|
+
* }),
|
|
349
|
+
* Match.exhaustive
|
|
350
|
+
* )
|
|
351
|
+
* ```
|
|
352
|
+
*
|
|
353
|
+
* @category Defining patterns
|
|
60
354
|
* @since 1.0.0
|
|
61
355
|
*/
|
|
62
356
|
export const discriminators = internal.discriminators;
|
|
63
357
|
/**
|
|
64
|
-
*
|
|
358
|
+
* Matches values based on a discriminator field and **ensures all cases are
|
|
359
|
+
* handled**.
|
|
360
|
+
*
|
|
361
|
+
* **Details*+
|
|
362
|
+
*
|
|
363
|
+
* This function is similar to {@link discriminators}, but **requires that all
|
|
364
|
+
* possible cases** are explicitly handled. It is useful when working with
|
|
365
|
+
* discriminated unions, where a specific field (e.g., `"type"`) determines the
|
|
366
|
+
* shape of an object. Each possible value of the field must have a
|
|
367
|
+
* corresponding handler, ensuring **exhaustiveness checking** at compile time.
|
|
368
|
+
*
|
|
369
|
+
* This function **does not require** `Match.exhaustive` at the end of the
|
|
370
|
+
* pipeline because it enforces exhaustiveness by design.
|
|
371
|
+
*
|
|
372
|
+
* @example
|
|
373
|
+
* ```ts
|
|
374
|
+
* import { Match, pipe } from "effect"
|
|
375
|
+
*
|
|
376
|
+
* const match = pipe(
|
|
377
|
+
* Match.type<{ type: "A"; a: string } | { type: "B"; b: number } | { type: "C"; c: boolean }>(),
|
|
378
|
+
* Match.discriminatorsExhaustive("type")({
|
|
379
|
+
* A: (a) => a.a,
|
|
380
|
+
* B: (b) => b.b,
|
|
381
|
+
* C: (c) => c.c
|
|
382
|
+
* })
|
|
383
|
+
* )
|
|
384
|
+
* ```
|
|
385
|
+
*
|
|
386
|
+
* @category Defining patterns
|
|
65
387
|
* @since 1.0.0
|
|
66
388
|
*/
|
|
67
389
|
export const discriminatorsExhaustive = internal.discriminatorsExhaustive;
|
|
68
390
|
/**
|
|
69
|
-
*
|
|
391
|
+
* The `Match.tag` function allows pattern matching based on the `_tag` field in
|
|
392
|
+
* a [Discriminated Union](https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes-func.html#discriminated-unions).
|
|
393
|
+
* You can specify multiple tags to match within a single pattern.
|
|
394
|
+
*
|
|
395
|
+
* **Note**
|
|
396
|
+
*
|
|
397
|
+
* The `Match.tag` function relies on the convention within the Effect ecosystem
|
|
398
|
+
* of naming the tag field as `"_tag"`. Ensure that your discriminated unions
|
|
399
|
+
* follow this naming convention for proper functionality.
|
|
400
|
+
*
|
|
401
|
+
* @example
|
|
402
|
+
* ```ts
|
|
403
|
+
* // Title: Matching a Discriminated Union by Tag
|
|
404
|
+
* import { Match } from "effect"
|
|
405
|
+
*
|
|
406
|
+
* type Event =
|
|
407
|
+
* | { readonly _tag: "fetch" }
|
|
408
|
+
* | { readonly _tag: "success"; readonly data: string }
|
|
409
|
+
* | { readonly _tag: "error"; readonly error: Error }
|
|
410
|
+
* | { readonly _tag: "cancel" }
|
|
411
|
+
*
|
|
412
|
+
* // Create a Matcher for Either<number, string>
|
|
413
|
+
* const match = Match.type<Event>().pipe(
|
|
414
|
+
* // Match either "fetch" or "success"
|
|
415
|
+
* Match.tag("fetch", "success", () => `Ok!`),
|
|
416
|
+
* // Match "error" and extract the error message
|
|
417
|
+
* Match.tag("error", (event) => `Error: ${event.error.message}`),
|
|
418
|
+
* // Match "cancel"
|
|
419
|
+
* Match.tag("cancel", () => "Cancelled"),
|
|
420
|
+
* Match.exhaustive
|
|
421
|
+
* )
|
|
422
|
+
*
|
|
423
|
+
* console.log(match({ _tag: "success", data: "Hello" }))
|
|
424
|
+
* // Output: "Ok!"
|
|
425
|
+
*
|
|
426
|
+
* console.log(match({ _tag: "error", error: new Error("Oops!") }))
|
|
427
|
+
* // Output: "Error: Oops!"
|
|
428
|
+
* ```
|
|
429
|
+
*
|
|
430
|
+
* @category Defining patterns
|
|
70
431
|
* @since 1.0.0
|
|
71
432
|
*/
|
|
72
433
|
export const tag = internal.tag;
|
|
73
434
|
/**
|
|
74
|
-
*
|
|
435
|
+
* Matches values where the `_tag` field starts with a given prefix.
|
|
436
|
+
*
|
|
437
|
+
* **Details**
|
|
438
|
+
*
|
|
439
|
+
* This function allows you to match on values in a **discriminated union**
|
|
440
|
+
* based on whether the `_tag` field starts with a specified prefix. It is
|
|
441
|
+
* useful for handling hierarchical or namespaced tags, where multiple related
|
|
442
|
+
* cases share a common prefix.
|
|
443
|
+
*
|
|
444
|
+
* @example
|
|
445
|
+
* ```ts
|
|
446
|
+
* import { Match, pipe } from "effect"
|
|
447
|
+
*
|
|
448
|
+
* const match = pipe(
|
|
449
|
+
* Match.type<{ _tag: "A" } | { _tag: "B" } | { _tag: "A.A" } | {}>(),
|
|
450
|
+
* Match.tagStartsWith("A", (_) => 1 as const),
|
|
451
|
+
* Match.tagStartsWith("B", (_) => 2 as const),
|
|
452
|
+
* Match.orElse((_) => 3 as const)
|
|
453
|
+
* )
|
|
454
|
+
*
|
|
455
|
+
* console.log(match({ _tag: "A" })) // 1
|
|
456
|
+
* console.log(match({ _tag: "B" })) // 2
|
|
457
|
+
* console.log(match({ _tag: "A.A" })) // 1
|
|
458
|
+
* ```
|
|
459
|
+
*
|
|
460
|
+
* @category Defining patterns
|
|
75
461
|
* @since 1.0.0
|
|
76
462
|
*/
|
|
77
463
|
export const tagStartsWith = internal.tagStartsWith;
|
|
78
464
|
/**
|
|
79
|
-
*
|
|
465
|
+
* Matches values based on their `_tag` field, mapping each tag to a
|
|
466
|
+
* corresponding handler.
|
|
467
|
+
*
|
|
468
|
+
* **Details**
|
|
469
|
+
*
|
|
470
|
+
* This function provides a way to handle discriminated unions by mapping `_tag`
|
|
471
|
+
* values to specific functions. Each handler receives the matched value and
|
|
472
|
+
* returns a transformed result. If all possible tags are handled, you can
|
|
473
|
+
* enforce exhaustiveness using `Match.exhaustive` to ensure no case is missed.
|
|
474
|
+
*
|
|
475
|
+
* @example
|
|
476
|
+
* ```ts
|
|
477
|
+
* import { Match, pipe } from "effect"
|
|
478
|
+
*
|
|
479
|
+
* const match = pipe(
|
|
480
|
+
* Match.type<{ _tag: "A"; a: string } | { _tag: "B"; b: number } | { _tag: "C"; c: boolean }>(),
|
|
481
|
+
* Match.tags({
|
|
482
|
+
* A: (a) => a.a,
|
|
483
|
+
* B: (b) => b.b,
|
|
484
|
+
* C: (c) => c.c
|
|
485
|
+
* }),
|
|
486
|
+
* Match.exhaustive
|
|
487
|
+
* )
|
|
488
|
+
* ```
|
|
489
|
+
*
|
|
490
|
+
* @category Defining patterns
|
|
80
491
|
* @since 1.0.0
|
|
81
492
|
*/
|
|
82
493
|
export const tags = internal.tags;
|
|
83
494
|
/**
|
|
84
|
-
*
|
|
495
|
+
* Matches values based on their `_tag` field and requires handling of all
|
|
496
|
+
* possible cases.
|
|
497
|
+
*
|
|
498
|
+
* **Details**
|
|
499
|
+
*
|
|
500
|
+
* This function is designed for **discriminated unions** where every possible
|
|
501
|
+
* `_tag` value must have a corresponding handler. Unlike {@link tags}, this
|
|
502
|
+
* function ensures **exhaustiveness**, meaning all cases must be explicitly
|
|
503
|
+
* handled. If a `_tag` value is missing from the mapping, TypeScript will
|
|
504
|
+
* report an error.
|
|
505
|
+
*
|
|
506
|
+
* @example
|
|
507
|
+
* ```ts
|
|
508
|
+
* import { Match, pipe } from "effect"
|
|
509
|
+
*
|
|
510
|
+
* const match = pipe(
|
|
511
|
+
* Match.type<{ _tag: "A"; a: string } | { _tag: "B"; b: number } | { _tag: "C"; c: boolean }>(),
|
|
512
|
+
* Match.tagsExhaustive({
|
|
513
|
+
* A: (a) => a.a,
|
|
514
|
+
* B: (b) => b.b,
|
|
515
|
+
* C: (c) => c.c
|
|
516
|
+
* })
|
|
517
|
+
* )
|
|
518
|
+
* ```
|
|
519
|
+
*
|
|
520
|
+
* @category Defining patterns
|
|
85
521
|
* @since 1.0.0
|
|
86
522
|
*/
|
|
87
523
|
export const tagsExhaustive = internal.tagsExhaustive;
|
|
88
524
|
/**
|
|
89
|
-
*
|
|
525
|
+
* Excludes a specific value from matching while allowing all others.
|
|
526
|
+
*
|
|
527
|
+
* **Details**
|
|
528
|
+
*
|
|
529
|
+
* This function is useful when you need to **handle all values except one or
|
|
530
|
+
* more specific cases**. Instead of listing all possible matches manually, this
|
|
531
|
+
* function simplifies the logic by allowing you to specify values to exclude.
|
|
532
|
+
* Any excluded value will bypass the provided function and continue matching
|
|
533
|
+
* through other cases.
|
|
534
|
+
*
|
|
535
|
+
* @example
|
|
536
|
+
* ```ts
|
|
537
|
+
* // Title: Ignoring a Specific Value
|
|
538
|
+
* import { Match } from "effect"
|
|
539
|
+
*
|
|
540
|
+
* // Create a matcher for string or number values
|
|
541
|
+
* const match = Match.type<string | number>().pipe(
|
|
542
|
+
* // Match any value except "hi", returning "ok"
|
|
543
|
+
* Match.not("hi", () => "ok"),
|
|
544
|
+
* // Fallback case for when the value is "hi"
|
|
545
|
+
* Match.orElse(() => "fallback")
|
|
546
|
+
* )
|
|
547
|
+
*
|
|
548
|
+
* console.log(match("hello"))
|
|
549
|
+
* // Output: "ok"
|
|
550
|
+
*
|
|
551
|
+
* console.log(match("hi"))
|
|
552
|
+
* // Output: "fallback"
|
|
553
|
+
* ```
|
|
554
|
+
*
|
|
555
|
+
* @category Defining patterns
|
|
90
556
|
* @since 1.0.0
|
|
91
557
|
*/
|
|
92
558
|
export const not = internal.not;
|
|
93
559
|
/**
|
|
94
|
-
*
|
|
560
|
+
* Matches non-empty strings.
|
|
561
|
+
*
|
|
562
|
+
* @category Predicates
|
|
95
563
|
* @since 1.0.0
|
|
96
564
|
*/
|
|
97
565
|
export const nonEmptyString = internal.nonEmptyString;
|
|
98
566
|
/**
|
|
99
|
-
*
|
|
567
|
+
* Matches a specific set of literal values (e.g., `Match.is("a", 42, true)`).
|
|
568
|
+
*
|
|
569
|
+
* @category Predicates
|
|
100
570
|
* @since 1.0.0
|
|
101
571
|
*/
|
|
102
572
|
export const is = internal.is;
|
|
103
573
|
/**
|
|
104
|
-
*
|
|
574
|
+
* Matches values of type `string`.
|
|
575
|
+
*
|
|
576
|
+
* @category Predicates
|
|
105
577
|
* @since 1.0.0
|
|
106
578
|
*/
|
|
107
579
|
export const string = Predicate.isString;
|
|
108
580
|
/**
|
|
109
|
-
*
|
|
581
|
+
* Matches values of type `number`.
|
|
582
|
+
*
|
|
583
|
+
* @category Predicates
|
|
110
584
|
* @since 1.0.0
|
|
111
585
|
*/
|
|
112
586
|
export const number = Predicate.isNumber;
|
|
113
587
|
/**
|
|
114
|
-
*
|
|
588
|
+
* Matches any value without restrictions.
|
|
589
|
+
*
|
|
590
|
+
* @category Predicates
|
|
115
591
|
* @since 1.0.0
|
|
116
592
|
*/
|
|
117
593
|
export const any = internal.any;
|
|
118
594
|
/**
|
|
119
|
-
*
|
|
595
|
+
* Matches any defined (non-null and non-undefined) value.
|
|
596
|
+
*
|
|
597
|
+
* @category Predicates
|
|
120
598
|
* @since 1.0.0
|
|
121
599
|
*/
|
|
122
600
|
export const defined = internal.defined;
|
|
123
601
|
/**
|
|
124
|
-
*
|
|
602
|
+
* Matches values of type `boolean`.
|
|
603
|
+
*
|
|
604
|
+
* @category Predicates
|
|
125
605
|
* @since 1.0.0
|
|
126
606
|
*/
|
|
127
607
|
export const boolean = Predicate.isBoolean;
|
|
128
608
|
const _undefined = Predicate.isUndefined;
|
|
129
609
|
export {
|
|
130
610
|
/**
|
|
131
|
-
*
|
|
611
|
+
* Matches the value `undefined`.
|
|
612
|
+
*
|
|
613
|
+
* @category Predicates
|
|
132
614
|
* @since 1.0.0
|
|
133
615
|
*/
|
|
134
616
|
_undefined as undefined };
|
|
135
617
|
const _null = Predicate.isNull;
|
|
136
618
|
export {
|
|
137
619
|
/**
|
|
138
|
-
*
|
|
620
|
+
* Matches the value `null`.
|
|
621
|
+
*
|
|
622
|
+
* @category Predicates
|
|
139
623
|
* @since 1.0.0
|
|
140
624
|
*/
|
|
141
625
|
_null as null };
|
|
142
626
|
/**
|
|
143
|
-
*
|
|
627
|
+
* Matches values of type `bigint`.
|
|
628
|
+
*
|
|
629
|
+
* @category Predicates
|
|
144
630
|
* @since 1.0.0
|
|
145
631
|
*/
|
|
146
632
|
export const bigint = Predicate.isBigInt;
|
|
147
633
|
/**
|
|
148
|
-
*
|
|
634
|
+
* Matches values of type `symbol`.
|
|
635
|
+
*
|
|
636
|
+
* @category Predicates
|
|
149
637
|
* @since 1.0.0
|
|
150
638
|
*/
|
|
151
639
|
export const symbol = Predicate.isSymbol;
|
|
152
640
|
/**
|
|
153
|
-
*
|
|
641
|
+
* Matches values that are instances of `Date`.
|
|
642
|
+
*
|
|
643
|
+
* @category Predicates
|
|
154
644
|
* @since 1.0.0
|
|
155
645
|
*/
|
|
156
646
|
export const date = Predicate.isDate;
|
|
157
647
|
/**
|
|
158
|
-
*
|
|
648
|
+
* Matches objects where keys are `string` or `symbol` and values are `unknown`.
|
|
649
|
+
*
|
|
650
|
+
* @category Predicates
|
|
159
651
|
* @since 1.0.0
|
|
160
652
|
*/
|
|
161
653
|
export const record = Predicate.isRecord;
|
|
162
654
|
/**
|
|
163
|
-
*
|
|
655
|
+
* Matches instances of a given class.
|
|
656
|
+
*
|
|
657
|
+
* @category Predicates
|
|
164
658
|
* @since 1.0.0
|
|
165
659
|
*/
|
|
166
660
|
export const instanceOf = internal.instanceOf;
|
|
167
661
|
/**
|
|
168
|
-
* @category
|
|
662
|
+
* @category Predicates
|
|
169
663
|
* @since 1.0.0
|
|
170
664
|
*/
|
|
171
665
|
export const instanceOfUnsafe = internal.instanceOf;
|
|
172
666
|
/**
|
|
173
|
-
*
|
|
667
|
+
* Provides a fallback value when no patterns match.
|
|
668
|
+
*
|
|
669
|
+
* **Details**
|
|
670
|
+
*
|
|
671
|
+
* This function ensures that a matcher always returns a valid result, even if
|
|
672
|
+
* no defined patterns match. It acts as a default case, similar to the
|
|
673
|
+
* `default` clause in a `switch` statement or the final `else` in an `if-else`
|
|
674
|
+
* chain.
|
|
675
|
+
*
|
|
676
|
+
* @example
|
|
677
|
+
* ```ts
|
|
678
|
+
* // Title: Providing a Default Value When No Patterns Match
|
|
679
|
+
* import { Match } from "effect"
|
|
680
|
+
*
|
|
681
|
+
* // Create a matcher for string or number values
|
|
682
|
+
* const match = Match.type<string | number>().pipe(
|
|
683
|
+
* // Match when the value is "a"
|
|
684
|
+
* Match.when("a", () => "ok"),
|
|
685
|
+
* // Fallback when no patterns match
|
|
686
|
+
* Match.orElse(() => "fallback")
|
|
687
|
+
* )
|
|
688
|
+
*
|
|
689
|
+
* console.log(match("a"))
|
|
690
|
+
* // Output: "ok"
|
|
691
|
+
*
|
|
692
|
+
* console.log(match("b"))
|
|
693
|
+
* // Output: "fallback"
|
|
694
|
+
* ```
|
|
695
|
+
*
|
|
696
|
+
* @category Completion
|
|
174
697
|
* @since 1.0.0
|
|
175
698
|
*/
|
|
176
699
|
export const orElse = internal.orElse;
|
|
177
|
-
|
|
178
|
-
|
|
700
|
+
// TODO(4.0): Rename to "orThrow"? Like Either.getOrThrow
|
|
701
|
+
/**
|
|
702
|
+
* Throws an error if no pattern matches.
|
|
703
|
+
*
|
|
704
|
+
* **Details**
|
|
705
|
+
*
|
|
706
|
+
* This function finalizes a matcher by ensuring that if no patterns match, an
|
|
707
|
+
* error is thrown. It is useful when all cases should be covered, and any
|
|
708
|
+
* unexpected input should trigger an error instead of returning a default
|
|
709
|
+
* value.
|
|
710
|
+
*
|
|
711
|
+
* When used, this function removes the need for an explicit fallback case and
|
|
712
|
+
* ensures that an unmatched value is never silently ignored.
|
|
713
|
+
*
|
|
714
|
+
* @category Completion
|
|
179
715
|
* @since 1.0.0
|
|
180
716
|
*/
|
|
181
717
|
export const orElseAbsurd = internal.orElseAbsurd;
|
|
182
718
|
/**
|
|
183
|
-
*
|
|
719
|
+
* Wraps the match result in an `Either`, distinguishing matched and unmatched
|
|
720
|
+
* cases.
|
|
721
|
+
*
|
|
722
|
+
* **Details**
|
|
723
|
+
*
|
|
724
|
+
* This function ensures that the result of a matcher is always wrapped in an
|
|
725
|
+
* `Either`, allowing clear differentiation between successful matches
|
|
726
|
+
* (`Right(value)`) and cases where no pattern matched (`Left(unmatched
|
|
727
|
+
* value)`).
|
|
728
|
+
*
|
|
729
|
+
* This approach is particularly useful when handling optional values or when an
|
|
730
|
+
* unmatched case should be explicitly handled rather than returning a default
|
|
731
|
+
* value or throwing an error.
|
|
732
|
+
*
|
|
733
|
+
* @example
|
|
734
|
+
* ```ts
|
|
735
|
+
* // Title: Extracting a User Role with Either
|
|
736
|
+
* import { Match } from "effect"
|
|
737
|
+
*
|
|
738
|
+
* type User = { readonly role: "admin" | "editor" | "viewer" }
|
|
739
|
+
*
|
|
740
|
+
* // Create a matcher to extract user roles
|
|
741
|
+
* const getRole = Match.type<User>().pipe(
|
|
742
|
+
* Match.when({ role: "admin" }, () => "Has full access"),
|
|
743
|
+
* Match.when({ role: "editor" }, () => "Can edit content"),
|
|
744
|
+
* Match.either // Wrap the result in an Either
|
|
745
|
+
* )
|
|
746
|
+
*
|
|
747
|
+
* console.log(getRole({ role: "admin" }))
|
|
748
|
+
* // Output: { _id: 'Either', _tag: 'Right', right: 'Has full access' }
|
|
749
|
+
*
|
|
750
|
+
* console.log(getRole({ role: "viewer" }))
|
|
751
|
+
* // Output: { _id: 'Either', _tag: 'Left', left: { role: 'viewer' } }
|
|
752
|
+
* ```
|
|
753
|
+
*
|
|
754
|
+
* @category Completion
|
|
184
755
|
* @since 1.0.0
|
|
185
756
|
*/
|
|
186
757
|
export const either = internal.either;
|
|
187
758
|
/**
|
|
188
|
-
*
|
|
759
|
+
* Wraps the match result in an `Option`, representing an optional match.
|
|
760
|
+
*
|
|
761
|
+
* **Details**
|
|
762
|
+
*
|
|
763
|
+
* This function ensures that the result of a matcher is wrapped in an `Option`,
|
|
764
|
+
* making it easy to handle cases where no pattern matches. If a match is found,
|
|
765
|
+
* it returns `Some(value)`, otherwise, it returns `None`.
|
|
766
|
+
*
|
|
767
|
+
* This is useful in cases where a missing match is expected and should be
|
|
768
|
+
* handled explicitly rather than throwing an error or returning a default
|
|
769
|
+
* value.
|
|
770
|
+
*
|
|
771
|
+
* @example
|
|
772
|
+
* ```ts
|
|
773
|
+
* // Title: Extracting a User Role with Option
|
|
774
|
+
* import { Match } from "effect"
|
|
775
|
+
*
|
|
776
|
+
* type User = { readonly role: "admin" | "editor" | "viewer" }
|
|
777
|
+
*
|
|
778
|
+
* // Create a matcher to extract user roles
|
|
779
|
+
* const getRole = Match.type<User>().pipe(
|
|
780
|
+
* Match.when({ role: "admin" }, () => "Has full access"),
|
|
781
|
+
* Match.when({ role: "editor" }, () => "Can edit content"),
|
|
782
|
+
* Match.option // Wrap the result in an Option
|
|
783
|
+
* )
|
|
784
|
+
*
|
|
785
|
+
* console.log(getRole({ role: "admin" }))
|
|
786
|
+
* // Output: { _id: 'Option', _tag: 'Some', value: 'Has full access' }
|
|
787
|
+
*
|
|
788
|
+
* console.log(getRole({ role: "viewer" }))
|
|
789
|
+
* // Output: { _id: 'Option', _tag: 'None' }
|
|
790
|
+
* ```
|
|
791
|
+
*
|
|
792
|
+
* @category Completion
|
|
189
793
|
* @since 1.0.0
|
|
190
794
|
*/
|
|
191
795
|
export const option = internal.option;
|
|
192
796
|
/**
|
|
193
|
-
*
|
|
797
|
+
* The `Match.exhaustive` method finalizes the pattern matching process by
|
|
798
|
+
* ensuring that all possible cases are accounted for. If any case is missing,
|
|
799
|
+
* TypeScript will produce a type error. This is particularly useful when
|
|
800
|
+
* working with unions, as it helps prevent unintended gaps in pattern matching.
|
|
801
|
+
*
|
|
802
|
+
* @example
|
|
803
|
+
* ```ts
|
|
804
|
+
* // Title: Ensuring All Cases Are Covered
|
|
805
|
+
* import { Match } from "effect"
|
|
806
|
+
*
|
|
807
|
+
* // Create a matcher for string or number values
|
|
808
|
+
* const match = Match.type<string | number>().pipe(
|
|
809
|
+
* // Match when the value is a number
|
|
810
|
+
* Match.when(Match.number, (n) => `number: ${n}`),
|
|
811
|
+
* // Mark the match as exhaustive, ensuring all cases are handled
|
|
812
|
+
* // TypeScript will throw an error if any case is missing
|
|
813
|
+
* // @ts-expect-error Type 'string' is not assignable to type 'never'
|
|
814
|
+
* Match.exhaustive
|
|
815
|
+
* )
|
|
816
|
+
* ```
|
|
817
|
+
*
|
|
818
|
+
* @category Completion
|
|
194
819
|
* @since 1.0.0
|
|
195
820
|
*/
|
|
196
821
|
export const exhaustive = internal.exhaustive;
|
|
197
822
|
/**
|
|
198
823
|
* @since 1.0.0
|
|
199
|
-
* @category
|
|
824
|
+
* @category Symbols
|
|
200
825
|
*/
|
|
201
826
|
export const SafeRefinementId = /*#__PURE__*/Symbol.for("effect/SafeRefinement");
|
|
202
827
|
const Fail = /*#__PURE__*/Symbol.for("effect/Fail");
|