-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoption.js
executable file
·68 lines (56 loc) · 1.45 KB
/
option.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
var Type = require('union-type')
var curry = require('ramda').curry
var T = () => true
var Opt = Type({None: [], Some: [T]})
var Some = Opt.Some
var None = Opt.None
var none = None()
Opt.none = none
Opt.equals = curry((a, b) => Opt.case({
Some: v => b.name === 'Some' && v === Opt.extract(b)
, None: _ => b.name === 'None'
}, a))
//:: (a -> b) -> Opt a -> Opt b
Opt.map = curry((f, a) => Opt.case({
Some: v => Some(f(v))
, None: _ => none
}, a))
//:: Opt a -> a
Opt.extract = Opt.case({
Some: v => v
, None: _ => null
})
//:: a -> Opt _ -> Opt a
Opt.of = curry((a, b) => Opt.case({
Some: _ => Some(a)
, None: _ => Some(a)
}, b))
//:: (a -> Opt b) -> Opt a -> Opt b
Opt.chain = f => Opt.case({
Some: v => {
var b = f(v);
return b.name === "Some" ? b : none
}
, None: _ => none
})
//:: Opt a -> Opt (a -> b) -> Opt b
Opt.ap = curry((a, b) => Opt.case({
Some: v => b.name === "Some" ? Some(Opt.extract(b)(v)) : none
, None: _ => none
}, a))
//:: (b -> a -> b) -> b -> Opt a -> b
Opt.reduce = curry((f, b, a) => Opt.case({
Some: v => f(b, v)
, None: _ => b
}, a))
//:: Opt a => (a -> b) -> a -> Opt b
Opt.extend = curry((f, a) => Opt.case({
Some: _ => Some(f(a))
, None: _ => none
}, a))
//:: (a -> Boolean) -> Opt a -> Opt a
Opt.filter = curry((f, a) => Opt.case({
Some: v => f(v) ? a : none
, None: _ => none
}, a))
module.exports = Opt