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
|
package jsy.util
/*
* DoWith is a data structure that holds a function that returns a result of
* type R with a input-output state of type W.
*
* Aside: This is also known as the State monad.
*/
sealed class DoWith[W,+R] private (doer: W => (W,R)) {
def apply(w: W) = doer(w)
def map[B](f: R => B): DoWith[W,B] = new DoWith[W,B]({
(w: W) => {
val (wp, r) = doer(w)
(wp, f(r))
}
})
def flatMap[B](f: R => DoWith[W,B]): DoWith[W,B] = new DoWith[W,B]({
(w: W) => {
val (wp, r) = doer(w)
f(r)(wp) // same as f(a).apply(s)
}
})
}
object DoWith {
def doget[W]: DoWith[W, W] = new DoWith[W, W]({ w => (w, w) })
def doput[W](w: W): DoWith[W, Unit] = new DoWith[W, Unit]({ _ => (w, ()) })
def doreturn[W, R](r: R): DoWith[W, R] = new DoWith[W, R]({ w => (w, r) })
def domodify[W](f: W => W): DoWith[W, Unit] = new DoWith[W, Unit]({ w => (f(w), ()) })
}
|