Skip to content

Commit d1c40a9

Browse files
committed
feat: added funtion equals for Either
1 parent 1529022 commit d1c40a9

File tree

2 files changed

+101
-2
lines changed

2 files changed

+101
-2
lines changed

src/either/Either.ts

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@ export interface Either<L, R> {
77
chain<U>(fn: (value: R) => Either<L, U>): Either<L, U>;
88
unwrapOr(defaultValue: R): R;
99
match<T>(cases: { left: (left: L) => T; right: (right: R) => T }): T;
10+
equals(other: Either<L, R>): boolean;
11+
12+
extract(): L | R;
1013
}
1114

1215
export class Right<L, R> implements Either<L, R> {
13-
constructor(private readonly value: R) {}
16+
constructor(private readonly value: R) { }
1417

1518
isLeft(): boolean {
1619
return false;
@@ -39,10 +42,18 @@ export class Right<L, R> implements Either<L, R> {
3942
match<T>(cases: { left: (left: L) => T; right: (right: R) => T }): T {
4043
return cases.right(this.value);
4144
}
45+
46+
equals(other: Either<L, R>): boolean {
47+
return other.isRight() ? this.value === other.extract() : false;
48+
}
49+
50+
extract(): R {
51+
return this.value;
52+
}
4253
}
4354

4455
export class Left<L, R = unknown> implements Either<L, R> {
45-
constructor(private readonly value: L) {}
56+
constructor(private readonly value: L) { }
4657

4758
isLeft(): boolean {
4859
return true;
@@ -71,6 +82,14 @@ export class Left<L, R = unknown> implements Either<L, R> {
7182
match<T>(cases: { left: (left: L) => T; right: (right: R) => T }): T {
7283
return cases.left(this.value);
7384
}
85+
86+
equals(other: Either<L, R>): boolean {
87+
return other.isLeft() ? this.value === other.extract() : false;
88+
}
89+
90+
extract(): L {
91+
return this.value;
92+
}
7493
}
7594

7695
export const tryCatch = <L = unknown, R = unknown>(
@@ -138,3 +157,9 @@ export const matchE = <L, R, T>(
138157
) => (either: Either<L, R>): T => {
139158
return either.match(cases);
140159
};
160+
161+
export const equalsE = <L, R>(
162+
other: Either<L, R>
163+
) => (either: Either<L, R>): boolean => {
164+
return either.equals(other);
165+
};

tests/either.test.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { pipe } from "rambda";
22
import { chainE, fromAsync, fromPromise, Left, mapE, mapLeftE, matchE, Right, tryCatch, unwrapOrE } from "../src/either";
3+
import { equalsE } from "../src/either/Either";
34

45
describe("Either", () => {
56
it("Right.map applies function to value", () => {
@@ -88,6 +89,30 @@ describe("Either", () => {
8889
expect(new Left("x").isLeft()).toBe(true);
8990
});
9091

92+
it("Right.equals returns true for equal Right values", () => {
93+
const a = new Right(42);
94+
const b = new Right(42);
95+
expect(a.equals(b)).toBe(true);
96+
});
97+
98+
it("Left.equals returns true for equal Left values", () => {
99+
const a = new Left("error");
100+
const b = new Left("error");
101+
expect(a.equals(b)).toBe(true);
102+
});
103+
104+
it("Right.equals returns false for different Right values", () => {
105+
const a = new Right(42);
106+
const b = new Right(43);
107+
expect(a.equals(b)).toBe(false);
108+
});
109+
110+
it("Left.equals returns false for different Left values", () => {
111+
const a = new Left("error");
112+
const b = new Left("different error");
113+
expect(a.equals(b)).toBe(false);
114+
});
115+
91116
it("tryCatch should return Right when function succeeds", () => {
92117
const result = tryCatch(() => JSON.parse('{"a":1}'));
93118
expect(result.isRight()).toBe(true);
@@ -294,4 +319,53 @@ describe("Either - Curried Helpers", () => {
294319
);
295320
expect(result).toBe("error: Bad Request");
296321
});
322+
323+
it("should return true for equal Right values with curried equals", () => {
324+
const result = pipe(
325+
new Right(42),
326+
equalsE(new Right(42))
327+
);
328+
expect(result).toBe(true);
329+
});
330+
331+
it("should return false for different Right values with curried equals", () => {
332+
const result = pipe(
333+
new Right(42),
334+
equalsE(new Right(43))
335+
);
336+
expect(result).toBe(false);
337+
});
338+
339+
it("should return true for equal Left values with curried equals", () => {
340+
const result = pipe(
341+
new Left("error"),
342+
equalsE(new Left("error"))
343+
);
344+
expect(result).toBe(true);
345+
});
346+
347+
it("should return false for different Left values with curried equals", () => {
348+
const result = pipe(
349+
new Left("error"),
350+
equalsE(new Left("different error"))
351+
);
352+
expect(result).toBe(false);
353+
});
354+
355+
it("should return false for different Left and Right values with curried equals", () => {
356+
const result = pipe(
357+
new Left<string, number>("error"),
358+
equalsE(new Right(42))
359+
);
360+
expect(result).toBe(false);
361+
});
362+
363+
it("should return false for different Right and Left values with curried equals", () => {
364+
const result = pipe(
365+
new Right<string, number>(42),
366+
equalsE(new Left("error"))
367+
);
368+
expect(result).toBe(false);
369+
});
370+
297371
});

0 commit comments

Comments
 (0)