The Effect type carries the same idea with three channels instead of two.
A, the success value the effect produces on completion.
E, the typed expected error. Recoverable, narrowed by handlers (step 09).
R, the services the effect requires from context. Default never (no dependencies).
import { Effect } from "effect"
// ┌─── Effect<number, never, never>
const always42 = Effect.succeed(42)
// ┌─── Effect<never, string, never>
const alwaysFail = Effect.fail("something went wrong")
Read the types as: Effect<User, NotFound> succeeds with User or fails with NotFound. Effect<void, never> always succeeds.
Effect<never, FatalError> always fails.
Notice. never in the success position is not “no error” — it means the
Effect cannot succeed. The infallible shape is Effect<A, never>, with
never in the error position. The two channels read symmetrically.
Your turn: lift 42 into success and "oops" into failure so each program produces the expected Exit — the first asserts Exit.isSuccess, the second Exit.isFailure.