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 3304f10e20..313081fe4b 100644 --- a/packages/effect/src/internal/core.ts +++ b/packages/effect/src/internal/core.ts @@ -926,35 +926,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 7a1acf29d6..a918918da0 100644 --- a/packages/effect/src/internal/fiberRuntime.ts +++ b/packages/effect/src/internal/fiberRuntime.ts @@ -1597,7 +1597,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)