-
-
Notifications
You must be signed in to change notification settings - Fork 505
/
Reader.ts
60 lines (49 loc) · 1.7 KB
/
Reader.ts
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
import { reader, ask } from '../src/Reader'
// So, what's the Reader monad?
// Here's a shape of some data which will be useful later
interface Config {
name: string
age: number
}
// Here's an arbitrary value we are going to start using in our functions
const x = 1
// Our Reader monad, note it has not been given the context at this point
const read = reader.of<Config, number>(x)
// Let's start doing calculations with it!
const read2 = read
.map(x => x * 2) // multiply by 2!
.map(y => y + 10) // add 10! (why? why not!)
.chain(j => {
// Let's use something from the context!
// first we 'ask' for it
const conf = ask<Config>()
// It returns a new Reader monad with the context inside it
// we can't just grab the value, but we can map over it and
// thus return a new Reader monad
// because we are returning a new Monad note this function is chain
// instead of map
return conf.map(c => j + c.age)
})
.chain(age => {
// let's grab it again and use the name
const conf = ask<Config>()
// and combine the name with the age
return conf.map(c => `Hello ${c.name} you are now ${age} years old isn't that just lovely?`)
})
// what is read2 then?
// tslint:disable-next-line: no-console
console.log(read2)
// -> Reader { run: [Function] }
// a Reader monad!
// but what can we do with it?
// but what about if we have some context to put in it?
const config: Config = {
name: 'horse',
age: 100
}
// let's run our Reader with the stuff in it...
const output = read2.run(config)
// tslint:disable-next-line: no-console
console.log(output)
// -> "Hello horse you are now 112 years old isn't that just lovely?"
// So what is the Reader monad? Dependency injection!