(define (return val) (lambda (curr_counter) (cons curr_counter val))) (define (>>= m f) (lambda (curr_counter) (let* ((m_result (m curr_counter)) (n1 (car m_result)) ; result of the delayed computation (v (cdr 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) (>>= (lambda (n) (cons (+ 1 n) n)) (lambda (counter) (return (cons (cons 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)))))