@@ -238,6 +238,30 @@ export function wrap<A, S extends unknown[] = unknown[]>(
238238 return ( ...s ) => P . resolve ( [ E . right ( a ) , ...s ] ) ;
239239}
240240
241+ /**
242+ * Create a failed Effect with the given error value. The error is placed
243+ * in a Left and the input state is passed through unchanged. This is an
244+ * alias for left and is commonly used in contexts where you want to
245+ * emphasize failure.
246+ *
247+ * @example
248+ * ```ts
249+ * import * as Eff from "./effect.ts";
250+ * import * as E from "./either.ts";
251+ *
252+ * const errorEffect = Eff.fail("Something went wrong");
253+ * const result = await errorEffect("state");
254+ * // [E.left("Something went wrong"), "state"]
255+ * ```
256+ *
257+ * @since 3.0.0-rc.2
258+ */
259+ export function fail < B , S extends unknown [ ] = unknown [ ] > (
260+ b : B ,
261+ ) : Effect < S , B , never > {
262+ return ( ...s ) => P . resolve ( [ E . left ( b ) , ...s ] ) ;
263+ }
264+
241265/**
242266 * Create a successful Effect with the given value. This is an alias for wrap
243267 * and is commonly used in contexts where you want to emphasize success.
@@ -279,7 +303,43 @@ export function right<A, S extends unknown[] = unknown[]>(
279303export function left < B , S extends unknown [ ] = unknown [ ] > (
280304 b : B ,
281305) : Effect < S , B , never > {
282- return ( ...s ) => P . resolve ( [ E . left ( b ) , ...s ] ) ;
306+ return fail ( b ) ;
307+ }
308+
309+ /**
310+ * Swap the success and error values of an Effect. If the Effect contains
311+ * a Right (success), it becomes a Left (error) with the same value. If it
312+ * contains a Left (error), it becomes a Right (success) with the same value.
313+ * The state is passed through unchanged.
314+ *
315+ * @example
316+ * ```ts
317+ * import * as Eff from "./effect.ts";
318+ * import * as E from "./either.ts";
319+ * import { pipe } from "./fn.ts";
320+ *
321+ * const successEffect = Eff.right("success");
322+ * const swappedSuccess = Eff.swap(successEffect);
323+ *
324+ * const result1 = await swappedSuccess("state");
325+ * // [E.left("success"), "state"]
326+ *
327+ * const errorEffect = Eff.left("error");
328+ * const swappedError = Eff.swap(errorEffect);
329+ *
330+ * const result2 = await swappedError("state");
331+ * // [E.right("error"), "state"]
332+ * ```
333+ *
334+ * @since 3.0.0-rc.2
335+ */
336+ export function swap < S extends unknown [ ] , A , B , O extends unknown [ ] > (
337+ ua : Effect < S , B , A , O > ,
338+ ) : Effect < S , A , B , O > {
339+ return async ( ...s ) => {
340+ const [ ea , ...o ] = await ua . apply ( ua , s ) ;
341+ return [ E . swap ( ea ) , ...o ] ;
342+ } ;
283343}
284344
285345/**
@@ -391,6 +451,16 @@ export function mapSecond<B, J>(
391451 } ;
392452}
393453
454+ export function mapEither < B , A , I , J > (
455+ fee : ( ea : Either < B , A > ) => Either < J , I > ,
456+ ) : < S extends unknown [ ] , O extends unknown [ ] > (
457+ ua : Effect < S , B , A , O > ,
458+ ) => Effect < S , J , I , O > {
459+ return ( ua ) => async ( ...s ) => {
460+ const [ ea , ...o ] = await ua . apply ( ua , s ) ;
461+ return [ fee ( ea ) , ...o ] ;
462+ } ;
463+ }
394464/**
395465 * Apply a function wrapped in an Effect to a value wrapped in an Effect.
396466 * Both Effects must succeed for the application to succeed. The function
@@ -595,6 +665,28 @@ export function get<S extends unknown[]>(): Effect<S, never, S, S> {
595665 return ( ...s ) => Promise . resolve ( [ E . right ( s ) , ...s ] ) ;
596666}
597667
668+ /**
669+ * Get the current state as the error value of an Effect. This is the
670+ * dual of `get` - instead of returning the state as a success value
671+ * (Right), it returns the state as an error value (Left). The state
672+ * is both the error value and passed through unchanged.
673+ *
674+ * @example
675+ * ```ts
676+ * import * as Eff from "./effect.ts";
677+ * import * as E from "./either.ts";
678+ *
679+ * const getErrorState = Eff.getSecond<[string]>();
680+ * const result = await getErrorState("hello");
681+ * // [E.left(["hello"]), "hello"]
682+ * ```
683+ *
684+ * @since 3.0.0-rc.2
685+ */
686+ export function getSecond < S extends unknown [ ] > ( ) : Effect < S , S , never , S > {
687+ return ( ...s ) => Promise . resolve ( [ E . left ( s ) , ...s ] ) ;
688+ }
689+
598690/**
599691 * Replace the current state with a new value. The new state becomes
600692 * both the success value and the output state.
@@ -618,6 +710,31 @@ export function put<O extends unknown[], S extends unknown[] = unknown[]>(
618710 return ( ) => Promise . resolve ( [ E . right ( o ) , ...o ] ) ;
619711}
620712
713+ /**
714+ * Replace the current state with a new value as an error. This is the
715+ * dual of `put` - instead of returning the new state as a success value
716+ * (Right), it returns the new state as an error value (Left). The new
717+ * state becomes both the error value and the output state.
718+ *
719+ * @example
720+ * ```ts
721+ * import * as Eff from "./effect.ts";
722+ * import * as E from "./either.ts";
723+ *
724+ * const putErrorState = Eff.putSecond("new error state");
725+ *
726+ * const result = await putErrorState("old state");
727+ * // [E.left(["new error state"]), "new error state"]
728+ * ```
729+ *
730+ * @since 3.0.0-rc.2
731+ */
732+ export function putSecond < O extends unknown [ ] , S extends unknown [ ] = unknown [ ] > (
733+ ...o : O
734+ ) : Effect < S , O , never , O > {
735+ return ( ) => Promise . resolve ( [ E . left ( o ) , ...o ] ) ;
736+ }
737+
621738/**
622739 * Extract a value from the current state using a function, without
623740 * modifying the state. The extracted value becomes the success value.
@@ -645,6 +762,35 @@ export function gets<S extends unknown[], A>(
645762 return async ( ...s ) => [ E . right ( await fsa . apply ( fsa , s ) ) , ...s ] ;
646763}
647764
765+ /**
766+ * Extract a value from the current state using a function as an error value.
767+ * This is the dual of `gets` - instead of returning the extracted value as
768+ * a success value (Right), it returns the extracted value as an error value
769+ * (Left). The state is passed through unchanged.
770+ *
771+ * @example
772+ * ```ts
773+ * import * as Eff from "./effect.ts";
774+ * import * as E from "./either.ts";
775+ *
776+ * const getDoubledError = Eff.getsSecond((s: number) => s * 2);
777+ * const getAsyncError = Eff.getsSecond((s: number) => Promise.resolve(s * 2));
778+ *
779+ * const result1 = await getDoubledError(21);
780+ * // [E.left(42), 21]
781+ *
782+ * const result2 = await getAsyncError(21);
783+ * // [E.left(42), 21]
784+ * ```
785+ *
786+ * @since 3.0.0-rc.2
787+ */
788+ export function getsSecond < S extends unknown [ ] , B > (
789+ fsa : ( ...s : S ) => B | Promise < B > ,
790+ ) : Effect < S , B , never , S > {
791+ return async ( ...s ) => [ E . left ( await fsa . apply ( fsa , s ) ) , ...s ] ;
792+ }
793+
648794/**
649795 * Transform the current state using a function. The transformed value
650796 * becomes both the success value and the new state.
@@ -675,6 +821,38 @@ export function puts<S extends unknown[], O extends unknown[] = S>(
675821 } ;
676822}
677823
824+ /**
825+ * Transform the current state using a function as an error value. This is
826+ * the dual of `puts` - instead of returning the transformed state as a
827+ * success value (Right), it returns the transformed state as an error value
828+ * (Left). The transformed value becomes both the error value and the new state.
829+ *
830+ * @example
831+ * ```ts
832+ * import * as Eff from "./effect.ts";
833+ * import * as E from "./either.ts";
834+ *
835+ * const doubleErrorState = Eff.putsSecond((n: number) => [n * 2]);
836+ * const asyncPutsError = Eff.putsSecond((n: number) => Promise.resolve([n * 2]));
837+ *
838+ * const result1 = await doubleErrorState(21);
839+ * // [E.left([42]), 42]
840+ *
841+ * const result2 = await asyncPutsError(21);
842+ * // [E.left([42]), 42]
843+ * ```
844+ *
845+ * @since 3.0.0-rc.2
846+ */
847+ export function putsSecond < S extends unknown [ ] , O extends unknown [ ] = S > (
848+ fsa : ( ...s : S ) => O | Promise < O > ,
849+ ) : Effect < S , O , never , O > {
850+ return async ( ...s ) => {
851+ const o = await fsa . apply ( fsa , s ) ;
852+ return [ E . left ( o ) , ...o ] ;
853+ } ;
854+ }
855+
678856/**
679857 * Execute an Effect with the given initial state and return only the
680858 * result (Either), discarding the final state.
0 commit comments