Skip to content

Commit

Permalink
feat: 🎸 adds a tap function for running side-effects
Browse files Browse the repository at this point in the history
Provides a tap, as an alternative for a map function that doesn't change
the value.
  • Loading branch information
Retsam committed Nov 11, 2019
1 parent 4344d67 commit 16518c5
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 0 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,18 @@ const now: Array<number> = orig.map(x => parseInt(x));
none().map(v => console.log(v)) // does not print
```

### tap
Like `map`, it calls a function with the current value, if there is one, but ignores any return value and the result is always the original Maybe. Intended for running side-effects, without changing the value.

```typescript
some(1)
// If this was `.map`, then the result of this call would be None
.tap(x => console.log(`Original value is ${x}`))
.map(x => x + 1)
.tap(x => console.log(`New value is ${x}`))
```


### flatMap
FlatMap also accesses the contained value, but it expects that its "mapper" function returns a container of the same type.
Imagine the conceptually equivalent array container:
Expand Down
1 change: 1 addition & 0 deletions src/maybe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export default abstract class Maybe<T> {
abstract expect(msg?: string | Error): T;
abstract caseOf<R>(funcs: MatchType<T, R>): Maybe<R>;
abstract map<U>(f: (v: T) => Nullable<U>): Maybe<U>;
abstract tap(f: (v: T) => void): Maybe<T>;
abstract flatMap<U>(f: (v: T) => Maybe<U>): Maybe<U>;
abstract orElse<U>(def: U | (() => U)): T | U;
abstract or<U>(other: Maybe<U> | (() => Maybe<U>)): Maybe<T | U>;
Expand Down
4 changes: 4 additions & 0 deletions src/none.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ export default class None<T> extends Maybe<T> {
return this as any;
}

tap(): Maybe<T> {
return this;
}

flatMap<U>(): Maybe<U> {
return this as any;
}
Expand Down
6 changes: 6 additions & 0 deletions src/some.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ export default class Some<T> extends Maybe<T> {
return maybe<U>(f(this.value!));
}

tap(f: (v: T) => void): Maybe<T> {
f(this.value!);
return this;
}


flatMap<U>(f: (v: T) => Maybe<U>): Maybe<U> {
return f(this.value!);
}
Expand Down
23 changes: 23 additions & 0 deletions tests/maybe.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,29 @@ test('map - Gives back a maybe', checkInstance(
none().map(noop),
));

// ---
// Tap
// ---

test('Calls map function when contained value is non-nil', () => {
expect.assertions(2);

const value = "i'm not nil";
const definitely = some(value);

definitely
.tap(v => expect(v).toBe(value))
.tap(v => expect(v).toBe(value));
});

test('Does not call tap function when contained value is nil', () => {
none().tap(raiseError);
});

test('tap - Gives back a maybe', checkInstance(
none().tap(noop),
));

// --------
// Flat Map
// --------
Expand Down

0 comments on commit 16518c5

Please sign in to comment.