Skip to content

Commit cc4ffdc

Browse files
feat(either): introduce either.tap() (#19)
Allows functions to be executed as side effects without return values. Similar to either.map()
1 parent 923134b commit cc4ffdc

File tree

3 files changed

+69
-0
lines changed

3 files changed

+69
-0
lines changed

src/interfaces/either.interface.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export interface IEither<L, R> {
22
isLeft(): boolean
33
isRight(): boolean
44
match<T>(pattern: IEitherPattern<L, R, T>): T
5+
tap<T>(pattern: Partial<IEitherPattern<L, R, T>>): void
56
map<T>(f: (r: R) => T): IEither<L, T>
67
flatMap<T>(f: (r: R) => IEither<L, T>): IEither<L, T>
78
}

src/monads/either.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ export function either<L, R>(left?: L, right?: R): IEither<L, R> {
3838
? pattern.right(right as R)
3939
: pattern.left(left as L)
4040
},
41+
tap<T>(pattern: Partial<IEitherPattern<L, R, T>>) {
42+
exists(right)
43+
? pattern.right && pattern.right(right as R)
44+
: pattern.left && pattern.left(left as L)
45+
},
4146
map<T>(f: (r: R) => T) {
4247
return exists(right)
4348
? either<L, T>(undefined, f(right as R))

test/monads/either.spec.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,67 @@ describe(either.name, () => {
119119

120120
expect(mapped).toEqual(3)
121121
})
122+
123+
it('should tap left', () => {
124+
expect.assertions(6)
125+
126+
const input1 = 123
127+
const input2: number | undefined = undefined
128+
129+
const eitherThing = either(input1, input2)
130+
131+
const mapped1 = eitherThing
132+
.tap({
133+
right: _rightSideEffect => fail(),
134+
left: leftSideEffect => {
135+
expect(leftSideEffect).toEqual(123)
136+
}
137+
})
138+
139+
const mapped2 = eitherThing
140+
.tap({
141+
left: leftSideEffect => expect(leftSideEffect).toEqual(123)
142+
})
143+
const mapped3 = eitherThing
144+
.tap({
145+
right: _rightSideEffect => fail()
146+
})
147+
148+
const mapped4 = eitherThing.tap({})
149+
150+
expect(mapped1).toEqual(undefined)
151+
expect(mapped2).toEqual(undefined)
152+
expect(mapped3).toEqual(undefined)
153+
expect(mapped4).toEqual(undefined)
154+
})
155+
156+
it('should tap right', () => {
157+
expect.assertions(6)
158+
159+
const input1 = undefined
160+
const input2: number | undefined = 123
161+
162+
const eitherThing = either(input1, input2)
163+
164+
const mapped1 = eitherThing
165+
.tap({
166+
left: _leftSideEffect => fail(),
167+
right: rightSideEffect => expect(rightSideEffect).toEqual(123)
168+
})
169+
170+
const mapped2 = eitherThing
171+
.tap({
172+
left: _leftSideEffect => fail()
173+
})
174+
const mapped3 = eitherThing
175+
.tap({
176+
right: rightSideEffect => expect(rightSideEffect).toEqual(123)
177+
})
178+
const mapped4 = eitherThing.tap({})
179+
180+
expect(mapped1).toEqual(undefined)
181+
expect(mapped2).toEqual(undefined)
182+
expect(mapped3).toEqual(undefined)
183+
expect(mapped4).toEqual(undefined)
184+
})
122185
})

0 commit comments

Comments
 (0)