forked from gcanti/fp-ts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathReaderIO.ts
85 lines (70 loc) · 2.11 KB
/
ReaderIO.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
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
import { IO, io } from '../src/IO'
import { Monad2 } from '../src/Monad'
import { Reader } from '../src/Reader'
import * as readerT from '../src/ReaderT'
const readerTIO = readerT.getReaderT(io)
declare module '../src/HKT' {
interface URI2HKT2<L, A> {
ReaderIO: ReaderIO<L, A>
}
}
export const URI = 'ReaderIO'
export type URI = typeof URI
export class ReaderIO<E, A> {
readonly _A!: A
readonly _L!: E
readonly _URI!: URI
constructor(readonly run: (e: E) => IO<A>) {}
map<B>(f: (a: A) => B): ReaderIO<E, B> {
return new ReaderIO(readerTIO.map(f, this.run))
}
of<E, B>(b: B): ReaderIO<E, B> {
return of(b)
}
ap<B>(fab: ReaderIO<E, (a: A) => B>): ReaderIO<E, B> {
return new ReaderIO(readerTIO.ap(fab.run, this.run))
}
ap_<B, C>(this: ReaderIO<E, (b: B) => C>, fb: ReaderIO<E, B>): ReaderIO<E, C> {
return fb.ap(this)
}
chain<B>(f: (a: A) => ReaderIO<E, B>): ReaderIO<E, B> {
return new ReaderIO(readerTIO.chain(a => f(a).run, this.run))
}
}
const map = <E, A, B>(fa: ReaderIO<E, A>, f: (a: A) => B): ReaderIO<E, B> => {
return fa.map(f)
}
const of = <E, A>(a: A): ReaderIO<E, A> => {
return new ReaderIO(readerTIO.of(a))
}
const ap = <E, A, B>(fab: ReaderIO<E, (a: A) => B>, fa: ReaderIO<E, A>): ReaderIO<E, B> => {
return fa.ap(fab)
}
const chain = <E, A, B>(fa: ReaderIO<E, A>, f: (a: A) => ReaderIO<E, B>): ReaderIO<E, B> => {
return fa.chain(f)
}
const readerTask = readerT.ask(io)
export const ask = <E>(): ReaderIO<E, E> => {
return new ReaderIO(readerTask())
}
const readerTasks = readerT.asks(io)
export const asks = <E, A>(f: (e: E) => A): ReaderIO<E, A> => {
return new ReaderIO(readerTasks(f))
}
export const local = <E>(f: (e: E) => E) => <A>(fa: ReaderIO<E, A>): ReaderIO<E, A> => {
return new ReaderIO(e => fa.run(f(e)))
}
export const fromIO = <E, A>(fa: IO<A>): ReaderIO<E, A> => {
return new ReaderIO(() => fa)
}
const readerTfromReader = readerT.fromReader(io)
export const fromReader = <E, A>(fa: Reader<E, A>): ReaderIO<E, A> => {
return new ReaderIO(readerTfromReader(fa))
}
export const readerIO: Monad2<URI> = {
URI,
map,
of,
ap,
chain
}