(define (make-numbered-value tag val) (cons tag val)) (define (nvalue-tag tv) (car tv)) (define (nvalue-val tv) (cdr tv)) (define (return val) (lambda (curr_counter) (make-numbered-value curr_counter val))) (define incr (lambda (n) (make-numbered-value (+ 1 n) n))) (define (>>= m f) (lambda (curr_counter) (let* ((m_result (m curr_counter)) (n1 (nvalue-tag m_result)) ; result of the delayed computation (v (nvalue-val m_result)) ; represented by m (m1 (f v))) ; feed the result to f, get another m1 (m1 n1)))) ; The result of the bigger monad (define (make-node val kids) (>>= incr (lambda (counter) (return (cons (make-numbered-value counter val) kids))))) (define (build-btree-r depth) (if (zero? depth) (make-node depth '()) (>>= (build-btree-r (- depth 1)) (lambda (left-branch) (>>= (build-btree-r (- depth 1)) (lambda (right-branch) (make-node depth (list left-branch right-branch)))))))) (define (runM m init-counter) (m init-counter)) (runM (build-btree-r 3) 100) ; => (115 (114 . 3) ((106 . 2) ((102 . 1) ((100 . 0)) ((101 . 0))) ((105 . 1) ((103 . 0)) ((104 . 0)))) ((113 . 2) ((109 . 1) ((107 . 0)) ((108 . 0))) ((112 . 1) ((110 . 0)) ((111 . 0)))))