From 190eaeea1142bf94e239d7456ebf0bc631c1392d Mon Sep 17 00:00:00 2001 From: Nathaniel Nicandro Date: Mon, 11 May 2020 13:18:22 -0500 Subject: [PATCH] binding stuff --- jupyter-monads.el | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/jupyter-monads.el b/jupyter-monads.el index c31ae57..eb8f72c 100644 --- a/jupyter-monads.el +++ b/jupyter-monads.el @@ -71,29 +71,38 @@ (binder (lambda (vars) (if (zerop (length vars)) - `(jupyter-return-thunk ,@body) + `(let ((res (progn ,@body))) + (if res (jupyter-return res) + jupyter-io-nil)) `(jupyter-bind ,(cadar vars) (lambda (val) - (setq ,(caar vars) val) + ,@(unless (eq (caar vars) '_) + `((setq ,(caar vars) val))) ,(funcall binder (cdr vars)))))))) `(let ,(cons result (mapcar #'car varlist)) ;; nil is bound here to kick off the chain of binds. ;; TODO Is it safe to assume nil? (jupyter-bind jupyter-io-nil - ,(funcall binder varlist)) - ,result))) + ,(funcall binder varlist))))) (defun jupyter--do (&rest mfns) (cl-reduce (lambda (io-value mfn) (jupyter-bind io-value mfn)) - mfns :initial-value jupyter-io-nil)) + mfns :initial-value jupyter-current-io)) + +(defmacro jupyter-with-io (io &rest io-fns) + (declare (indent 1)) + ;; Thread IO through the monad, return the resulting IO-VALUE. + `(cl-reduce #'jupyter-bind + ,@io-fns :initial-value (jupyter-return ,io))) (defmacro jupyter-do (io &rest forms) - (declare (indent 1)) + (declare (indent 1) (debug (form &rest form))) `(let ((jupyter-current-io ,io)) (jupyter--do ,@forms))) + (defun jupyter-after (io-value io-fn) "Return an I/O action that binds IO-VALUE to IO-FN. That is, IO-FN is evaluated after binding IO-VALUE within the I/O