-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmaybe.js
75 lines (63 loc) · 1.72 KB
/
maybe.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/** @module */
"use strict"
const Monad = require("./monad")
const { wrap } = require("./utils")
/**
* @alias module:lib/maybe.Maybe
* @description Maybe type. Do not construct instances using `new Maybe()`, use `Just()`
* or `Nothing`. You can subclass using prototype inheritance directly.
*/
class Maybe extends Monad {
/**
* do not use the constructor, instead construct using `Just` or use the
* singleton `Nothing`.
*/
constructor() {
throw Error("use Just(value) or Nothing to construct instances")
}
return(value) {return Just(value)}
fail() {return Nothing}
join(stack, cb) {
if (this instanceof Just) {
const { doBlock } = stack[0]
cb(doBlock.next(wrap(this.fromJust(), stack.length)))
} else {
const { doBlock } = stack[stack.length - 1]
doBlock.next({ value: this.fail(), done: true })
cb(stack[0].doBlock.next({ value: this.fail(), done: false }))
}
}
toString() {
return this === Nothing ? "Nothing" : `Just(${this.fromJust()})`
}
}
/**
* @method
* @description Just constructor. You can check if an object is instance of Just simply
* by `o instanceof Just`. `o instanceof Maybe` will return true as well.
* @param {any} value
* @return {Right}
*/
function Just(value) {
return {
__proto__: Just.prototype,
fromJust() {return value},
}
}
Just.prototype = {
__proto__: Maybe.prototype,
}
/**
* @alias module:lib/maybe.Nothing
* @description A singleton. Like `null`. You can check that an object is
* `Nothing` by `o === Nothing`.
*/
const Nothing = (function Nothing() {
return {
__proto__: Maybe.prototype,
fromJust() {throw Error("Maybe.fromJust: Nothing")}
}
})()
module.exports = {
Maybe, Just, Nothing,
}