-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patheither-pratices.js
More file actions
85 lines (73 loc) · 1.71 KB
/
either-pratices.js
File metadata and controls
85 lines (73 loc) · 1.71 KB
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
76
77
78
79
80
81
82
83
84
85
const _ = require("ramda")
// Definitions
// ====================
const Right = (x) => ({
chain: (f) => f(x),
map: (f) => Right(f(x)),
fold: (f, g) => g(x),
toString: () => `Right(${x})`,
})
const Left = (x) => ({
chain: (f) => Left(x),
map: (f) => Left(x),
fold: (f, g) => f(x),
toString: () => `Left(${x})`,
})
const fromNullable = (x) => (x != null ? Right(x) : Left(null))
const tryCatch = (f) => {
try {
return Right(f())
} catch (e) {
return Left(e)
}
}
const logIt = (x) => {
console.log(x)
return x
}
const DB_REGEX = /postgres:\/\/([^:]+):([^@]+)@.*?\/(.+)$/i
// Exercise: Either
// Goal: Refactor each example using Either
// Bonus: no curlies
// =========================
// Ex1: Refactor streetName to use Either instead of nested if's
// =========================
const street = (user) =>
fromNullable(user.address)
.map((address) => address.street)
.fold(
() => "no street",
(x) => x
)
const streetName = (user) =>
fromNullable(user.address)
.chain((address) => fromNullable(address.street))
.map((street) => street.name)
.fold(
() => "no street",
(x) => x
)
const parseDbUrl = (cfg) =>
Right(cfg)
.chain((cfg) => tryCatch(() => JSON.parse(cfg)))
.map((c) => c.url.match(DB_REGEX))
.fold(
() => null,
(x) => x
)
// Ex3: Using Either and the functions above, refactor startApp
// =========================
const startApp = (cfg) =>
Right(cfg)
.chain((cfg) => fromNullable(parseDbUrl(cfg)))
.map(([_, user, password, db]) => `starting ${db}, ${user}, ${password}`)
.fold(
(x) => "can't get config",
(x) => x
)
module.exports = {
street,
streetName,
parseDbUrl,
startApp,
}