Skip to content

Commit e95a7ea

Browse files
feat: introduce util functions (#15)
BREAKING CHANGE: separated interfaces/monads/util into their own folders. Any previously referenced interfaces must be changed to import from "typescript-monads/interfaces".
1 parent d3d036d commit e95a7ea

File tree

19 files changed

+132
-49
lines changed

19 files changed

+132
-49
lines changed

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
],
2121
"scripts": {
2222
"test": "jest",
23+
"test.watch": "jest --watch",
2324
"build": "tsc",
2425
"dist": "node_modules/.bin/ts-node ./scripts/publish-prep.ts",
2526
"lint": "tslint --project tsconfig.json --config tslint.json"
@@ -48,14 +49,15 @@
4849
"jest": {
4950
"testURL": "http://localhost",
5051
"collectCoverage": true,
52+
"collectCoverageFrom": ["src/**/*.ts"],
5153
"reporters": [
5254
"default",
5355
"jest-junit"
5456
],
5557
"transform": {
5658
"^.+\\.tsx?$": "ts-jest"
5759
},
58-
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
60+
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(ts?)$",
5961
"moduleFileExtensions": [
6062
"ts",
6163
"tsx",

src/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export { monad, IMonad } from './monad'
2-
export { maybe, IMaybe, IMaybePattern } from './maybe'
3-
export { either, IEither, IEitherPattern } from './either'
4-
export { reader, IReader } from './reader'
1+
export { monad } from './monads/monad'
2+
export { maybe } from './monads/maybe'
3+
export { either } from './monads/either'
4+
export { reader } from './monads/reader'

src/interfaces/either.interface.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export interface IEither<L, R> {
2+
isLeft(): boolean
3+
isRight(): boolean
4+
match<T>(pattern: IEitherPattern<L, R, T>): T
5+
map<T>(f: (r: R) => T): IEither<L, T>
6+
flatMap<T>(f: (r: R) => IEither<L, T>): IEither<L, T>
7+
}
8+
9+
export interface IEitherPattern<L, R, T> {
10+
left(l: L): T
11+
right(r: R): T
12+
}

src/interfaces/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export { IEither, IEitherPattern } from './either.interface'
2+
export { IMaybe, IMaybePattern } from './maybe.interface'
3+
export { mapping, IMonad } from './monad.interface'
4+
export { IReader } from './reader.interface'

src/maybe.ts renamed to src/interfaces/maybe.interface.ts

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { IMonad } from "./monad"
1+
import { IMonad } from "./monad.interface"
22

33
/**
44
* Define a contract to unwrap Maybe object
@@ -51,16 +51,4 @@ export interface IMaybe<T> extends IMonad<T> {
5151

5252
// tslint:disable-next-line:readonly-array
5353
of(x?: T, ...args: any[]): IMaybe<T>
54-
}
55-
56-
export function maybe<T>(value?: T): IMaybe<T> {
57-
return {
58-
of: (x) => maybe(x),
59-
valueOr: (val: T) => value === null || value === undefined ? val : value,
60-
valueOrCompute: (f: () => T) => value === null || value === undefined ? f() : value,
61-
tap: (obj: IMaybePattern<T, void>) => value === null || value === undefined ? obj.none() : obj.some(value),
62-
match: <R>(pattern: IMaybePattern<T, R>) => value === null || value === undefined ? pattern.none() : pattern.some(value),
63-
map: <R>(f: (t: T) => R) => value === null || value === undefined ? maybe<R>() : maybe<R>(f(value)),
64-
flatMap: <R>(f: (d: T) => IMaybe<R>) => value === null || value === undefined ? maybe<R>() : f(value)
65-
}
6654
}

src/interfaces/monad.interface.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// tslint:disable:readonly-array
2+
export type mapping<T, U> = (x: T, ...args: any[]) => U
3+
4+
export interface IMonad<T> {
5+
of(x: T, ...args: any[]): IMonad<T>
6+
flatMap<U>(f: mapping<T, IMonad<U>>): IMonad<U>
7+
}

src/interfaces/reader.interface.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export interface IReader<E, A> {
2+
of(fn: (config: E) => A): IReader<E, A>,
3+
run(config: E): A,
4+
map<B>(fn: (val: A) => B): IReader<E, B>
5+
flatMap<B>(fn: (val: A) => IReader<E, B>): IReader<E, B>,
6+
}

src/either.ts renamed to src/monads/either.ts

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,4 @@
1-
export interface IEither<L, R> {
2-
isLeft(): boolean
3-
isRight(): boolean
4-
match<T>(pattern: IEitherPattern<L, R, T>): T
5-
map<T>(f: (r: R) => T): IEither<L, T>
6-
flatMap<T>(f: (r: R) => IEither<L, T>): IEither<L, T>
7-
}
8-
9-
export interface IEitherPattern<L, R, T> {
10-
left(l: L): T
11-
right(r: R): T
12-
}
1+
import { IEither, IEitherPattern } from "../interfaces"
132

143
function exists<T>(t: T) {
154
return t !== null && t !== undefined

src/monads/maybe.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { IMaybe, IMaybePattern } from "../interfaces"
2+
3+
export function maybe<T>(value?: T): IMaybe<T> {
4+
return {
5+
of: (x) => maybe(x),
6+
valueOr: (val: T) => value === null || value === undefined ? val : value,
7+
valueOrCompute: (f: () => T) => value === null || value === undefined ? f() : value,
8+
tap: (obj: IMaybePattern<T, void>) => value === null || value === undefined ? obj.none() : obj.some(value),
9+
match: <R>(pattern: IMaybePattern<T, R>) => value === null || value === undefined ? pattern.none() : pattern.some(value),
10+
map: <R>(f: (t: T) => R) => value === null || value === undefined ? maybe<R>() : maybe<R>(f(value)),
11+
flatMap: <R>(f: (d: T) => IMaybe<R>) => value === null || value === undefined ? maybe<R>() : f(value)
12+
}
13+
}

src/monad.ts renamed to src/monads/monad.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
1-
// tslint:disable:readonly-array
2-
export type mapping<T, U> = (x: T, ...args: any[]) => U
3-
4-
export interface IMonad<T> {
5-
of(x: T, ...args: any[]): IMonad<T>
6-
flatMap<U>(f: mapping<T, IMonad<U>>): IMonad<U>
7-
}
1+
import { mapping, IMonad } from "../interfaces"
82

3+
// tslint:disable:readonly-array
94
export function monad<T>(x: T, ...args: any[]): IMonad<T> {
105
return {
116
of: (x: T, ...args: any[]) => monad<T>(x, ...args),

0 commit comments

Comments
 (0)