aboutsummaryrefslogtreecommitdiff
path: root/control/monad/state-minimal.scm
blob: aa7b1a0e39cd1052710140945589a81cb20a606e (plain)
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
(use-modules (ice-9 curried-definitions)
             (ice-9 match))

;;; This is a minimal implementation of the state monad.
;;; It is incompatible with the rest of my monad system,
;;; since everything either has type <pair> or <procedure>.
;;; But it should work as a nice base for the actual
;;; implementation.

;;; This implementation works, as far as I can tell, exactly
;;; like the Haskell version (of MonadState). But obviously
;;; without all the nice syntax.

;; newtype State = st-list -> st-list

;; State
(define ((get) st-list)
  "Sets the return value to the state value"
  (match st-list
    ((v st)
     (list st st))))

;; v -> State
(define ((put v) st-list)
  "Sets the state value to v, sets the return value to ()"
  (list '() v))

;; State -> (v -> State) -> State
(define ((bind st-proc proc) st-list)
  (let ((new-st-list (st-proc st-list)))
    (match new-st-list
      ((v _)
       ((proc v) new-st-list)))))

;; State -> State -> State
(define ((then st-proc-1 st-proc-b) st-list-a)
  (let ((st-list-b (st-proc-1 st-list-a)))
    (st-proc-b st-list-b)))

;; v -> State
(define ((return v) st-list)
  "Sets the return value to v"
  (cons v (cdr st-list)))

;; State -> v -> (r v)
(define (run-state st-proc init)
  "Exec state with init as starting state value"
  (st-proc (list init init)))