diff --git a/.changeset/fair-scissors-compare.md b/.changeset/fair-scissors-compare.md new file mode 100644 index 0000000000..4741842dd6 --- /dev/null +++ b/.changeset/fair-scissors-compare.md @@ -0,0 +1,31 @@ +--- +"effect": minor +--- + +Remove Effect.unified and Effect.unifiedFn in favour of Unify.unify. + +The `Unify` module fully replaces the need for specific unify functions, when before you did: + +```ts +import { Effect } from "effect"; + +const effect = Effect.unified( + Math.random() > 0.5 ? Effect.succeed("OK") : Effect.fail("NO") +); +const effectFn = Effect.unifiedFn((n: number) => + Math.random() > 0.5 ? Effect.succeed("OK") : Effect.fail("NO") +); +``` + +You can now do: + +```ts +import { Effect, Unify } from "effect"; + +const effect = Unify.unify( + Math.random() > 0.5 ? Effect.succeed("OK") : Effect.fail("NO") +); +const effectFn = Unify.unify((n: number) => + Math.random() > 0.5 ? Effect.succeed("OK") : Effect.fail("NO") +); +``` diff --git a/packages/cli/src/internal/cliApp.ts b/packages/cli/src/internal/cliApp.ts index 3256551674..ccd8cc2240 100644 --- a/packages/cli/src/internal/cliApp.ts +++ b/packages/cli/src/internal/cliApp.ts @@ -8,6 +8,7 @@ import * as HashMap from "effect/HashMap" import * as Option from "effect/Option" import { pipeArguments } from "effect/Pipeable" import * as ReadonlyArray from "effect/ReadonlyArray" +import * as Unify from "effect/Unify" import type * as BuiltInOptions from "../BuiltInOptions.js" import type * as CliApp from "../CliApp.js" import type * as CliConfig from "../CliConfig.js" @@ -80,7 +81,7 @@ export const run = dual< // Handle the command return Effect.matchEffect(InternalCommand.parse(self.command, prefixedArgs, config), { onFailure: (e) => Effect.zipRight(printDocs(e.error), Effect.fail(e)), - onSuccess: Effect.unifiedFn((directive) => { + onSuccess: Unify.unify((directive) => { switch (directive._tag) { case "UserDefined": { return ReadonlyArray.matchLeft(directive.leftover, { diff --git a/packages/effect/src/Effect.ts b/packages/effect/src/Effect.ts index f40df93ff5..806c6efa16 100644 --- a/packages/effect/src/Effect.ts +++ b/packages/effect/src/Effect.ts @@ -19,7 +19,7 @@ import type * as FiberRef from "./FiberRef.js" import type * as FiberRefs from "./FiberRefs.js" import type * as FiberRefsPatch from "./FiberRefsPatch.js" import type { LazyArg } from "./Function.js" -import { dual, identity } from "./Function.js" +import { dual } from "./Function.js" import type * as HashMap from "./HashMap.js" import type * as HashSet from "./HashSet.js" import type { TypeLambda } from "./HKT.js" @@ -212,15 +212,6 @@ export declare namespace Effect { readonly _E: Covariant readonly _R: Covariant } - /** - * @since 2.0.0 - * @category models - */ - export type Unify> = Effect< - Success, - Error, - Context - > /** * @since 2.0.0 * @category type-level @@ -4656,28 +4647,6 @@ export const withMetric: { (self: Effect, metric: Metric.Metric): Effect } = effect.withMetric -// ------------------------------------------------------------------------------------- -// unify -// ------------------------------------------------------------------------------------- - -/** - * Used to unify functions that would otherwise return `Effect | Effect` - * - * @category unify - * @since 2.0.0 - */ -export const unifiedFn: , Ret extends Effect>( - f: (...args: Args) => Ret -) => (...args: Args) => Effect.Unify = core.unified - -/** - * Used to unify effects that would otherwise be `Effect | Effect` - * - * @category unify - * @since 2.0.0 - */ -export const unified: >(f: Ret) => Effect.Unify = identity - // ------------------------------------------------------------------------------------- // semaphore // ------------------------------------------------------------------------------------- diff --git a/packages/effect/src/internal/core-effect.ts b/packages/effect/src/internal/core-effect.ts index bef5208681..1de093ab42 100644 --- a/packages/effect/src/internal/core-effect.ts +++ b/packages/effect/src/internal/core-effect.ts @@ -168,10 +168,13 @@ export const catchAllDefect = dual< self: Effect.Effect, f: (defect: unknown) => Effect.Effect ) => Effect.Effect ->(2, (self, f) => +>(2, ( + self: Effect.Effect, + f: (defect: unknown) => Effect.Effect +): Effect.Effect => core.catchAllCause( self, - core.unified((cause) => { + (cause): Effect.Effect => { const option = internalCause.find(cause, (_) => internalCause.isDieType(_) ? Option.some(_) : Option.none()) switch (option._tag) { case "None": { @@ -181,7 +184,7 @@ export const catchAllDefect = dual< return f(option.value.defect) } } - }) + } )) /* @internal */ @@ -226,10 +229,13 @@ export const catchSomeDefect = dual< ) => Effect.Effect >( 2, - (self, pf) => + ( + self: Effect.Effect, + pf: (defect: unknown) => Option.Option> + ): Effect.Effect => core.catchAllCause( self, - core.unified((cause) => { + (cause): Effect.Effect => { const option = internalCause.find(cause, (_) => internalCause.isDieType(_) ? Option.some(_) : Option.none()) switch (option._tag) { case "None": { @@ -240,7 +246,7 @@ export const catchSomeDefect = dual< return optionEffect._tag === "Some" ? optionEffect.value : core.failCause(cause) } } - }) + } ) ) diff --git a/packages/effect/src/internal/core.ts b/packages/effect/src/internal/core.ts index bb65d74250..b7be98886c 100644 --- a/packages/effect/src/internal/core.ts +++ b/packages/effect/src/internal/core.ts @@ -530,15 +530,6 @@ export const catchAll: { ): Effect.Effect => matchEffect(self, { onFailure: f, onSuccess: succeed }) ) -/** - * @macro identity - * @internal - */ -export const unified = , Ret extends Effect.Effect>( - f: (...args: Args) => Ret -) => -(...args: Args): Effect.Effect.Unify => f(...args) - /* @internal */ export const catchIf: { ( @@ -941,7 +932,7 @@ export const if_ = dual< (self: boolean | Effect.Effect, { onFalse, onTrue }: { readonly onTrue: Effect.Effect readonly onFalse: Effect.Effect - }) => typeof self === "boolean" ? (self ? onTrue : onFalse) : flatMap(self, unified((b) => (b ? onTrue : onFalse))) + }) => typeof self === "boolean" ? (self ? onTrue : onFalse) : flatMap(self, (b) => (b ? onTrue : onFalse)) ) /* @internal */ @@ -1051,7 +1042,7 @@ export const onError: { } = dual(2, ( self: Effect.Effect, cleanup: (cause: Cause.Cause) => Effect.Effect -): Effect.Effect => onExit(self, unified((exit) => exitIsSuccess(exit) ? unit : cleanup(exit.i0)))) +): Effect.Effect => onExit(self, (exit) => exitIsSuccess(exit) ? unit : cleanup(exit.i0))) /* @internal */ export const onExit: { diff --git a/packages/platform/test/Http/Multipart.test.ts b/packages/platform/test/Http/Multipart.test.ts index ea3aacaefc..cc6f25b629 100644 --- a/packages/platform/test/Http/Multipart.test.ts +++ b/packages/platform/test/Http/Multipart.test.ts @@ -1,5 +1,5 @@ import * as Multipart from "@effect/platform/Http/Multipart" -import { Chunk, Effect, identity, Stream } from "effect" +import { Chunk, Effect, identity, Stream, Unify } from "effect" import { assert, describe, test } from "vitest" describe("Multipart", () => { @@ -15,7 +15,7 @@ describe("Multipart", () => { Stream.fromReadableStream(() => response.body!, identity), Stream.pipeThroughChannel(Multipart.makeChannel(Object.fromEntries(response.headers))), Stream.mapEffect((part) => { - return Effect.unified( + return Unify.unify( part._tag === "File" ? Effect.zip( Effect.succeed(part.name),