forked from markhibberd/introduction-to-fp-in-scala
-
Notifications
You must be signed in to change notification settings - Fork 5
/
State.scala
101 lines (91 loc) · 1.86 KB
/
State.scala
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package patterns
import intro._
/*
* A state data type that represents the threading
* of some state value through computations.
*/
case class State[S, A](run: S => (S, A)) {
/*
* Exercise 4.1:
*
* Implement map for State[S, A].
*
* The following laws must hold:
* 1) r.map(z => z) == r
* 2) r.map(z => f(g(z))) == r.map(g).map(f)
*
*/
def map[B](f: A => B): State[S, B] =
???
/*
* Exercise 4.2:
*
* Implement flatMap (a.k.a. bind, a.k.a. >>=).
*
* The following law must hold:
* r.flatMap(f).flatMap(g) == r.flatMap(z => f(z).flatMap(g))
*
*/
def flatMap[B](f: A => State[S, B]): State[S, B] =
???
}
object State {
/*
* Exercise 4.3:
*
* Implement value (a.k.a. return, point, pure).
*
* Hint: Try using State constructor.
*/
def value[S, A](a: => A): State[S, A] =
???
/*
* Exercise 4.4:
*
* Implement get.
*
* Get provides access to the current state (S).
*
* Hint: Try using State constructor.
*/
def get[S]: State[S, S] =
???
/*
* Exercise 4.5:
*
* Implement gets.
*
* Gets provides access to a view of the current state (S).
*
* Hint: Try building on get.
*/
def gets[S, A](f: S => A): State[S, A] =
???
/*
* Exercise 4.6:
*
* Implement modify.
*
* Update the current state and produce no value.
*
* Hint: Try using State constructor.
*/
def modify[S](f: S => S): State[S, Unit] =
???
/*
* Exercise 4.7:
*
* Implement put.
*
* Clobber the current state and produce no value.
*
* Hint: Try building on modify.
*/
def put[S](s: S): State[S, Unit] =
???
implicit def StateMonad[S]: Monad[State[S, ?]] =
new Monad[State[S, ?]] {
def point[A](a: => A) = value(a)
def bind[A, B](a: State[S, A])(f: A => State[S, B]): State[S, B] = a flatMap f
}
}