-
Notifications
You must be signed in to change notification settings - Fork 2
/
stateM.ss
86 lines (73 loc) · 1.52 KB
/
stateM.ss
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
(library (monad stateM)
(export stateM
unit-state
bind-state
lookup-state
run-state
eval-state
exec-state
get-state
put-state
mod-state
push-state
pop-state)
(import (chezscheme)
(monad core))
(define unit-state
(lambda (a)
(lambda (s)
`(,a . ,s))))
(define bind-state
(lambda (m f)
(lambda (s)
(let ((p (m s)))
(let ((a^ (car p))
(s^ (cdr p)))
(let ((m^ (f a^)))
(m^ s^)))))))
(define lookup-state
(lambda (get)
(lambda (x)
(doM (env <- (get))
(unit-state
(cond
((assq x env) => cdr)
(else x)))))))
(define run-state
(lambda (m s)
(m s)))
(define eval-state
(lambda (m s)
(car (run-state m s))))
(define exec-state
(lambda (m s)
(cdr (run-state m s))))
(define get-state
(lambda ()
(lambda (s)
`(,s . ,s))))
(define put-state
(lambda (s^)
(mod-state (lambda (s) s^))))
(define mod-state
(lambda (f)
(lambda (s)
(let ((s^ (f s)))
`(_ . ,s^)))))
(define push-state
(lambda (s^)
(mod-state
(lambda (s)
(cons s^ s)))))
(define pop-state
(lambda ()
(doM (s <- (get-state))
(mod-state cdr)
(unit-state (car s)))))
(define-monad stateM
unit-state
bind-state
mzero-err
mplus-err
lift-err)
)