| title | Modeling Tagged Unions with Data.case | |||||||
|---|---|---|---|---|---|---|---|---|
| id | data-case | |||||||
| skillLevel | intermediate | |||||||
| applicationPatternId | core-concepts | |||||||
| summary | Use Data.case to create tagged unions (algebraic data types) for robust, type-safe domain modeling and pattern matching. | |||||||
| tags |
|
|||||||
| rule |
|
|||||||
| related |
|
|||||||
| author | PaulJPhilp | |||||||
| lessonOrder | 9 |
Use Data.case to create tagged unions (algebraic data types, or ADTs) for robust, type-safe domain modeling.
Tagged unions make it easy to represent and exhaustively handle all possible states of your domain entities.
Modeling domain logic with tagged unions ensures that all cases are handled, prevents illegal states, and enables safe, exhaustive pattern matching.
Data.case provides a concise, type-safe way to define and use ADTs in your application.
import { Data } from "effect";
// Define a tagged union for a simple state machine
type State = Data.TaggedEnum<{
Loading: {};
Success: { data: string };
Failure: { error: string };
}>;
const { Loading, Success, Failure } = Data.taggedEnum<State>();
// Create instances
const state1: State = Loading();
const state2: State = Success({ data: "Hello" });
const state3: State = Failure({ error: "Oops" });
// Pattern match on the state
function handleState(state: State): string {
switch (state._tag) {
case "Loading":
return "Loading...";
case "Success":
return `Data: ${state.data}`;
case "Failure":
return `Error: ${state.error}`;
}
}Explanation:
Data.casecreates tagged constructors for each state.- The
_tagproperty enables exhaustive pattern matching. - Use for domain modeling, state machines, and error types.
Using plain objects or enums for domain states, which can lead to illegal states, missed cases, and less type-safe pattern matching.