| title | Control Flow with Conditional Combinators | ||||||
|---|---|---|---|---|---|---|---|
| id | control-flow-with-combinators | ||||||
| skillLevel | intermediate | ||||||
| applicationPatternId | core-concepts | ||||||
| summary | Use combinators like Effect.if, Effect.when, and Effect.cond to handle conditional logic in a declarative, composable way. | ||||||
| tags |
|
||||||
| rule |
|
||||||
| related |
|
||||||
| author | Sandro Maglione | ||||||
| lessonOrder | 3 |
Use declarative combinators like Effect.if, Effect.when, and
Effect.unless to execute effects based on runtime conditions.
These combinators allow you to embed conditional logic directly into your
.pipe() compositions, maintaining a declarative style for simple branching.
import { Effect } from "effect";
const attemptAdminAction = (user: { isAdmin: boolean }) =>
Effect.if(user.isAdmin, {
onTrue: () => Effect.succeed("Admin action completed."),
onFalse: () => Effect.fail("Permission denied."),
});
const program = Effect.gen(function* () {
// Try with admin user
yield* Effect.logInfo("\nTrying with admin user...");
const adminResult = yield* Effect.either(
attemptAdminAction({ isAdmin: true })
);
yield* Effect.logInfo(
`Admin result: ${adminResult._tag === "Right" ? adminResult.right : adminResult.left}`
);
// Try with non-admin user
yield* Effect.logInfo("\nTrying with non-admin user...");
const userResult = yield* Effect.either(
attemptAdminAction({ isAdmin: false })
);
yield* Effect.logInfo(
`User result: ${userResult._tag === "Right" ? userResult.right : userResult.left}`
);
});
Effect.runPromise(program);Explanation:
Effect.if and related combinators allow you to branch logic without leaving
the Effect world or breaking the flow of composition.
Using Effect.gen for a single, simple conditional check can be more verbose
than necessary. For simple branching, Effect.if is often more concise.