(define (println n)
(display n)
(newline))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define call/cc call-with-current-continuation)
(define stack '())
(define (now)
(call/cc
(lambda (cc)
(cc cc))))
(define (push cc)
(set! stack (cons cc stack)))
(define (next)
(if (null? stack) '()
(let ((head (car stack)))
(set! stack (cdr stack))
(head head))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; List Monad:
(define (list_get x)
(let ((cc (now)))
(if (null? x)
(next)
(let ((head (car x)))
(set! x (cdr x))
(push cc)
head))))
(define (list_results_return x)
(reverse (delete '() x)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Maybe Monad:
(define (maybe_get x)
(if (null? x)
(next)
(car x)))
(define (maybe_results_return x)
(if (null? x)
"Nothing"
(car x)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (monadic_call get results_return func . args)
(define results '())
(define first '())
(let ((cc (now)))
(if (null? first)
(begin
(push cc)
(set! first 1)
(set! results (cons (apply func (cons get args)) results))
(next))
(results_return results))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (user_func get Mx My)
(define x '())
(define y '())
(set! x (get Mx))
(if (< x 1000)
(begin
(set! y (get My))
(* x y))
'()))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(begin
(println "normal call:")
(println (user_func car '(10) '(11))))
(begin
(println "list call:")
(println
(monadic_call list_get list_results_return user_func '(10 100 1000) '(1 2 3))))
(begin
(println "maybe call:")
(println
(monadic_call maybe_get maybe_results_return user_func '(10) '(11))))
(begin
(println "maybe call with Nothing:")
(println
(monadic_call maybe_get maybe_results_return user_func '() '(11))))