diff --git a/.changeset/three-poems-beg.md b/.changeset/three-poems-beg.md
new file mode 100644
index 0000000000..586661d37a
--- /dev/null
+++ b/.changeset/three-poems-beg.md
@@ -0,0 +1,23 @@
+---
+"effect": minor
+---
+
+use LazyArg for Effect.if branches
+
+Instead of:
+
+```ts
+Effect.if(true, {
+ onTrue: Effect.succeed("true"),
+ onFalse: Effect.succeed("false"),
+});
+```
+
+You should now write:
+
+```ts
+Effect.if(true, {
+ onTrue: () => Effect.succeed("true"),
+ onFalse: () => Effect.succeed("false"),
+});
+```
diff --git a/packages/effect/src/Effect.ts b/packages/effect/src/Effect.ts
index 1c6ce1619d..7636f8c552 100644
--- a/packages/effect/src/Effect.ts
+++ b/packages/effect/src/Effect.ts
@@ -3340,16 +3340,12 @@ export const option: (self: Effect) => Effect
const if_: {
(
- options: { readonly onTrue: Effect; readonly onFalse: Effect }
+ options: { readonly onTrue: LazyArg>; readonly onFalse: LazyArg> }
): (self: boolean | Effect) => Effect
- (
- self: boolean,
- options: { readonly onTrue: Effect; readonly onFalse: Effect }
- ): Effect
- (
- self: Effect,
- options: { readonly onTrue: Effect; readonly onFalse: Effect }
- ): Effect
+ (
+ self: boolean | Effect,
+ options: { readonly onTrue: LazyArg>; readonly onFalse: LazyArg> }
+ ): Effect
} = core.if_
export {
diff --git a/packages/effect/src/internal/core.ts b/packages/effect/src/internal/core.ts
index a85bdf32bf..58b041cdc4 100644
--- a/packages/effect/src/internal/core.ts
+++ b/packages/effect/src/internal/core.ts
@@ -925,35 +925,33 @@ export const forEachSequentialDiscard: {
export const if_ = dual<
(
options: {
- readonly onTrue: Effect.Effect
- readonly onFalse: Effect.Effect
+ readonly onTrue: LazyArg>
+ readonly onFalse: LazyArg>
}
) => (
self: Effect.Effect | boolean
) => Effect.Effect,
- {
- (
- self: boolean,
- options: {
- readonly onTrue: Effect.Effect
- readonly onFalse: Effect.Effect
- }
- ): Effect.Effect
- (
- self: Effect.Effect,
- options: {
- readonly onTrue: Effect.Effect
- readonly onFalse: Effect.Effect
- }
- ): Effect.Effect
- }
+ (
+ self: Effect.Effect | boolean,
+ options: {
+ readonly onTrue: LazyArg>
+ readonly onFalse: LazyArg>
+ }
+ ) => Effect.Effect
>(
(args) => typeof args[0] === "boolean" || isEffect(args[0]),
- (self: boolean | Effect.Effect, { onFalse, onTrue }: {
- readonly onTrue: Effect.Effect
- readonly onFalse: Effect.Effect
- // eslint-disable-next-line no-extra-boolean-cast
- }) => isEffect(self) ? flatMap(self, (b) => (b ? onTrue : onFalse)) : Boolean(self) ? onTrue : onFalse
+ (
+ self: Effect.Effect | boolean,
+ options: {
+ readonly onTrue: LazyArg>
+ readonly onFalse: LazyArg>
+ }
+ ): Effect.Effect =>
+ isEffect(self)
+ ? flatMap(self, (b): Effect.Effect => (b ? options.onTrue() : options.onFalse()))
+ : self
+ ? options.onTrue()
+ : options.onFalse()
)
/* @internal */
diff --git a/packages/effect/src/internal/fiberRuntime.ts b/packages/effect/src/internal/fiberRuntime.ts
index c8e90354f0..7ca383e073 100644
--- a/packages/effect/src/internal/fiberRuntime.ts
+++ b/packages/effect/src/internal/fiberRuntime.ts
@@ -1606,7 +1606,7 @@ export const exists: {
core.matchEffect(
forEach(
elements,
- (a, i) => core.if_(f(a, i), { onTrue: core.fail(_existsParFound), onFalse: core.unit }),
+ (a, i) => core.if_(f(a, i), { onTrue: () => core.fail(_existsParFound), onFalse: () => core.unit }),
options
),
{
diff --git a/packages/effect/test/Effect/cause-rendering.test.ts b/packages/effect/test/Effect/cause-rendering.test.ts
index 059e3e201f..93d805d4e4 100644
--- a/packages/effect/test/Effect/cause-rendering.test.ts
+++ b/packages/effect/test/Effect/cause-rendering.test.ts
@@ -30,8 +30,8 @@ describe("Effect", () => {
const effect = Effect.withSpan("spanB")(
Effect.withSpan("spanA")(
Effect.if(Effect.sync(() => Math.random() > 1), {
- onTrue: Effect.fail(new E2()),
- onFalse: Effect.fail(err)
+ onTrue: () => Effect.fail(new E2()),
+ onFalse: () => Effect.fail(err)
})
)
).pipe(Effect.catchTag("E2", (e) => Effect.die(e)))
@@ -55,8 +55,8 @@ describe("Effect", () => {
const effect = Effect.withSpan("spanB")(
Effect.withSpan("spanA")(
Effect.if(Effect.sync(() => Math.random() > 1), {
- onTrue: Effect.fail(new E2()),
- onFalse: Effect.fail(new E1())
+ onTrue: () => Effect.fail(new E2()),
+ onFalse: () => Effect.fail(new E1())
})
)
).pipe(Effect.catchAll((e) => Effect.fail(e)))
@@ -76,8 +76,8 @@ describe("Effect", () => {
const effect = Effect.withSpan("spanB")(
Effect.withSpan("spanA")(
Effect.if(Effect.sync(() => Math.random() > 1), {
- onTrue: Effect.fail(new E2()),
- onFalse: Effect.fail(new E1())
+ onTrue: () => Effect.fail(new E2()),
+ onFalse: () => Effect.fail(new E1())
})
)
).pipe(Effect.catchTags({ E2: (e) => Effect.die(e) }))
diff --git a/packages/effect/test/Effect/sequencing.test.ts b/packages/effect/test/Effect/sequencing.test.ts
index c5652269af..3de8a5800d 100644
--- a/packages/effect/test/Effect/sequencing.test.ts
+++ b/packages/effect/test/Effect/sequencing.test.ts
@@ -71,8 +71,8 @@ describe("Effect", () => {
const result = yield* $(
true,
Effect.if({
- onTrue: Effect.succeed(true),
- onFalse: Effect.succeed(false)
+ onTrue: () => Effect.succeed(true),
+ onFalse: () => Effect.succeed(false)
})
)
assert.isTrue(result)
@@ -82,8 +82,8 @@ describe("Effect", () => {
const result = yield* $(
Effect.succeed(false),
Effect.if({
- onFalse: Effect.succeed(true),
- onTrue: Effect.succeed(false)
+ onFalse: () => Effect.succeed(true),
+ onTrue: () => Effect.succeed(false)
})
)
assert.isTrue(result)