Skip to content

Commit aa2d60b

Browse files
authored
Move fantasy-land methods to the prototypes and implement Node.js inspect() (#750)
1 parent 3953749 commit aa2d60b

5 files changed

Lines changed: 130 additions & 44 deletions

File tree

src/Either.ts

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,14 @@ class Right<R, L = never> implements Either<L, R> {
172172
return `Right(${this.__value})`
173173
}
174174

175+
[Symbol.for('nodejs.util.inspect.custom')](
176+
_depth: number,
177+
opts: unknown,
178+
inspect: Function
179+
) {
180+
return `Right(${inspect(this.__value, opts)})`
181+
}
182+
175183
toString(): string {
176184
return this.inspect()
177185
}
@@ -272,16 +280,24 @@ class Right<R, L = never> implements Either<L, R> {
272280
return left(this.__value)
273281
}
274282

275-
'fantasy-land/bimap' = this.bimap
276-
'fantasy-land/map' = this.map
277-
'fantasy-land/ap' = this.ap
278-
'fantasy-land/equals' = this.equals
279-
'fantasy-land/chain' = this.chain
280-
'fantasy-land/alt' = this.alt
281-
'fantasy-land/reduce' = this.reduce
282-
'fantasy-land/extend' = this.extend
283+
declare 'fantasy-land/bimap': typeof this.bimap
284+
declare 'fantasy-land/map': typeof this.map
285+
declare 'fantasy-land/ap': typeof this.ap
286+
declare 'fantasy-land/equals': typeof this.equals
287+
declare 'fantasy-land/chain': typeof this.chain
288+
declare 'fantasy-land/alt': typeof this.alt
289+
declare 'fantasy-land/reduce': typeof this.reduce
290+
declare 'fantasy-land/extend': typeof this.extend
283291
}
284292

293+
Right.prototype['fantasy-land/bimap'] = Right.prototype.bimap
294+
Right.prototype['fantasy-land/map'] = Right.prototype.map
295+
Right.prototype['fantasy-land/ap'] = Right.prototype.ap
296+
Right.prototype['fantasy-land/equals'] = Right.prototype.equals
297+
Right.prototype['fantasy-land/chain'] = Right.prototype.chain
298+
Right.prototype['fantasy-land/alt'] = Right.prototype.alt
299+
Right.prototype['fantasy-land/reduce'] = Right.prototype.reduce
300+
Right.prototype['fantasy-land/extend'] = Right.prototype.extend
285301
Right.prototype.constructor = Either as any
286302

287303
class Left<L, R = never> implements Either<L, R> {
@@ -305,6 +321,14 @@ class Left<L, R = never> implements Either<L, R> {
305321
return `Left(${JSON.stringify(this.__value)})`
306322
}
307323

324+
[Symbol.for('nodejs.util.inspect.custom')](
325+
_depth: number,
326+
opts: unknown,
327+
inspect: Function
328+
) {
329+
return `Left(${inspect(this.__value, opts)})`
330+
}
331+
308332
toString(): string {
309333
return this.inspect()
310334
}
@@ -409,16 +433,24 @@ class Left<L, R = never> implements Either<L, R> {
409433
return right(this.__value)
410434
}
411435

412-
'fantasy-land/bimap' = this.bimap
413-
'fantasy-land/map' = this.map
414-
'fantasy-land/ap' = this.ap
415-
'fantasy-land/equals' = this.equals
416-
'fantasy-land/chain' = this.chain
417-
'fantasy-land/alt' = this.alt
418-
'fantasy-land/reduce' = this.reduce
419-
'fantasy-land/extend' = this.extend
436+
declare 'fantasy-land/bimap': typeof this.bimap
437+
declare 'fantasy-land/map': typeof this.map
438+
declare 'fantasy-land/ap': typeof this.ap
439+
declare 'fantasy-land/equals': typeof this.equals
440+
declare 'fantasy-land/chain': typeof this.chain
441+
declare 'fantasy-land/alt': typeof this.alt
442+
declare 'fantasy-land/reduce': typeof this.reduce
443+
declare 'fantasy-land/extend': typeof this.extend
420444
}
421445

446+
Left.prototype['fantasy-land/bimap'] = Left.prototype.bimap
447+
Left.prototype['fantasy-land/map'] = Left.prototype.map
448+
Left.prototype['fantasy-land/ap'] = Left.prototype.ap
449+
Left.prototype['fantasy-land/equals'] = Left.prototype.equals
450+
Left.prototype['fantasy-land/chain'] = Left.prototype.chain
451+
Left.prototype['fantasy-land/alt'] = Left.prototype.alt
452+
Left.prototype['fantasy-land/reduce'] = Left.prototype.reduce
453+
Left.prototype['fantasy-land/extend'] = Left.prototype.extend
422454
Left.prototype.constructor = Either as any
423455

424456
const left = <L, R = never>(value: L): Either<L, R> => new Left(value)

src/EitherAsync.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,14 +296,18 @@ class EitherAsyncImpl<L, R> implements EitherAsync<L, R> {
296296
)
297297
}
298298

299-
'fantasy-land/chain' = this.chain
300-
'fantasy-land/alt' = this.alt
299+
declare 'fantasy-land/chain': typeof this.chain
300+
declare 'fantasy-land/alt': typeof this.alt
301301

302302
then: PromiseLike<Either<L, R>>['then'] = (onfulfilled, onrejected) => {
303303
return this.run().then(onfulfilled, onrejected)
304304
}
305305
}
306306

307+
EitherAsyncImpl.prototype['fantasy-land/chain'] =
308+
EitherAsyncImpl.prototype.chain
309+
EitherAsyncImpl.prototype['fantasy-land/alt'] = EitherAsyncImpl.prototype.alt
310+
307311
export const EitherAsync: EitherAsyncTypeRef = Object.assign(
308312
<L, R>(
309313
runPromise: (helpers: EitherAsyncHelpers<L>) => PromiseLike<R>

src/Maybe.ts

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,14 @@ class Just<T> implements Maybe<T> {
203203
return `Just(${this.__value})`
204204
}
205205

206+
[Symbol.for('nodejs.util.inspect.custom')](
207+
_depth: number,
208+
opts: unknown,
209+
inspect: Function
210+
) {
211+
return `Just(${inspect(this.__value, opts)})`
212+
}
213+
206214
toString(): string {
207215
return this.inspect()
208216
}
@@ -304,16 +312,24 @@ class Just<T> implements Maybe<T> {
304312
return pred(this.__value) ? just(this.__value) : nothing
305313
}
306314

307-
'fantasy-land/equals' = this.equals
308-
'fantasy-land/map' = this.map
309-
'fantasy-land/ap' = this.ap
310-
'fantasy-land/alt' = this.alt
311-
'fantasy-land/chain' = this.chain
312-
'fantasy-land/reduce' = this.reduce
313-
'fantasy-land/extend' = this.extend
314-
'fantasy-land/filter' = this.filter
315+
declare 'fantasy-land/equals': typeof this.equals
316+
declare 'fantasy-land/map': typeof this.map
317+
declare 'fantasy-land/ap': typeof this.ap
318+
declare 'fantasy-land/alt': typeof this.alt
319+
declare 'fantasy-land/chain': typeof this.chain
320+
declare 'fantasy-land/reduce': typeof this.reduce
321+
declare 'fantasy-land/extend': typeof this.extend
322+
declare 'fantasy-land/filter': typeof this.filter
315323
}
316324

325+
Just.prototype['fantasy-land/equals'] = Just.prototype.equals
326+
Just.prototype['fantasy-land/map'] = Just.prototype.map
327+
Just.prototype['fantasy-land/ap'] = Just.prototype.ap
328+
Just.prototype['fantasy-land/alt'] = Just.prototype.alt
329+
Just.prototype['fantasy-land/chain'] = Just.prototype.chain
330+
Just.prototype['fantasy-land/reduce'] = Just.prototype.reduce
331+
Just.prototype['fantasy-land/extend'] = Just.prototype.extend
332+
Just.prototype['fantasy-land/filter'] = Just.prototype.filter
317333
Just.prototype.constructor = Maybe as any
318334

319335
class Nothing implements Maybe<never> {
@@ -331,6 +347,10 @@ class Nothing implements Maybe<never> {
331347
return 'Nothing'
332348
}
333349

350+
[Symbol.for('nodejs.util.inspect.custom')]() {
351+
return 'Nothing'
352+
}
353+
334354
toString(): string {
335355
return this.inspect()
336356
}
@@ -431,16 +451,24 @@ class Nothing implements Maybe<never> {
431451
return nothing
432452
}
433453

434-
'fantasy-land/equals' = this.equals
435-
'fantasy-land/map' = this.map
436-
'fantasy-land/ap' = this.ap
437-
'fantasy-land/alt' = this.alt
438-
'fantasy-land/chain' = this.chain
439-
'fantasy-land/reduce' = this.reduce
440-
'fantasy-land/extend' = this.extend
441-
'fantasy-land/filter' = this.filter
454+
declare 'fantasy-land/equals': typeof this.equals
455+
declare 'fantasy-land/map': typeof this.map
456+
declare 'fantasy-land/ap': typeof this.ap
457+
declare 'fantasy-land/alt': typeof this.alt
458+
declare 'fantasy-land/chain': typeof this.chain
459+
declare 'fantasy-land/reduce': typeof this.reduce
460+
declare 'fantasy-land/extend': typeof this.extend
461+
declare 'fantasy-land/filter': typeof this.filter
442462
}
443463

464+
Nothing.prototype['fantasy-land/equals'] = Nothing.prototype.equals
465+
Nothing.prototype['fantasy-land/map'] = Nothing.prototype.map
466+
Nothing.prototype['fantasy-land/ap'] = Nothing.prototype.ap
467+
Nothing.prototype['fantasy-land/alt'] = Nothing.prototype.alt
468+
Nothing.prototype['fantasy-land/chain'] = Nothing.prototype.chain
469+
Nothing.prototype['fantasy-land/reduce'] = Nothing.prototype.reduce
470+
Nothing.prototype['fantasy-land/extend'] = Nothing.prototype.extend
471+
Nothing.prototype['fantasy-land/filter'] = Nothing.prototype.filter
444472
Nothing.prototype.constructor = Maybe as any
445473

446474
/** Constructs a Just. Represents an optional value that exists */

src/MaybeAsync.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,10 +223,6 @@ class MaybeAsyncImpl<T> implements MaybeAsync<T> {
223223
)
224224
}
225225

226-
'fantasy-land/chain' = this.chain
227-
'fantasy-land/filter' = this.filter
228-
'fantasy-land/alt' = this.alt
229-
230226
then<TResult1 = Maybe<T>, TResult2 = never>(
231227
onfulfilled?:
232228
| ((value: Maybe<T>) => TResult1 | PromiseLike<TResult1>)
@@ -239,8 +235,17 @@ class MaybeAsyncImpl<T> implements MaybeAsync<T> {
239235
): PromiseLike<TResult1 | TResult2> {
240236
return this.run().then(onfulfilled, onrejected)
241237
}
238+
239+
declare 'fantasy-land/chain': typeof this.chain
240+
declare 'fantasy-land/filter': typeof this.filter
241+
declare 'fantasy-land/alt': typeof this.alt
242242
}
243243

244+
MaybeAsyncImpl.prototype['fantasy-land/chain'] = MaybeAsyncImpl.prototype.chain
245+
MaybeAsyncImpl.prototype['fantasy-land/filter'] =
246+
MaybeAsyncImpl.prototype.filter
247+
MaybeAsyncImpl.prototype['fantasy-land/alt'] = MaybeAsyncImpl.prototype.alt
248+
244249
export const MaybeAsync: MaybeAsyncTypeRef = Object.assign(
245250
<T>(
246251
runPromise: (helpers: MaybeAsyncHelpers) => PromiseLike<T>

src/Tuple.ts

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,10 @@ class TupleImpl<F, S> implements Tuple<F, S> {
6565
[index: number]: F | S
6666
length: 2 = 2
6767

68-
constructor(private first: F, private second: S) {
68+
constructor(
69+
private first: F,
70+
private second: S
71+
) {
6972
this[0] = first
7073
this[1] = second
7174
}
@@ -85,6 +88,14 @@ class TupleImpl<F, S> implements Tuple<F, S> {
8588
)})`
8689
}
8790

91+
[Symbol.for('nodejs.util.inspect.custom')](
92+
_depth: number,
93+
opts: unknown,
94+
inspect: Function
95+
) {
96+
return `Tuple(${inspect(this.first, opts)}, ${inspect(this.second, opts)})`
97+
}
98+
8899
toString(): string {
89100
return this.inspect()
90101
}
@@ -137,13 +148,19 @@ class TupleImpl<F, S> implements Tuple<F, S> {
137148
return pred(this.first) || pred(this.second)
138149
}
139150

140-
'fantasy-land/equals' = this.equals
141-
'fantasy-land/bimap' = this.bimap
142-
'fantasy-land/map' = this.map
143-
'fantasy-land/reduce' = this.reduce
144-
'fantasy-land/ap' = this.ap
151+
declare 'fantasy-land/equals': typeof this.equals
152+
declare 'fantasy-land/bimap': typeof this.bimap
153+
declare 'fantasy-land/map': typeof this.map
154+
declare 'fantasy-land/reduce': typeof this.reduce
155+
declare 'fantasy-land/ap': typeof this.ap
145156
}
146157

158+
TupleImpl.prototype['fantasy-land/equals'] = TupleImpl.prototype.equals
159+
TupleImpl.prototype['fantasy-land/bimap'] = TupleImpl.prototype.bimap
160+
TupleImpl.prototype['fantasy-land/map'] = TupleImpl.prototype.map
161+
TupleImpl.prototype['fantasy-land/reduce'] = TupleImpl.prototype.reduce
162+
TupleImpl.prototype['fantasy-land/ap'] = TupleImpl.prototype.ap
163+
147164
export const Tuple: TupleTypeRef = Object.assign(
148165
<F, S>(fst: F, snd: S) => new TupleImpl(fst, snd),
149166
{

0 commit comments

Comments
 (0)