Skip to content

Instantly share code, notes, and snippets.

@einblicker
Created October 22, 2011 10:45
Show Gist options
  • Save einblicker/1305862 to your computer and use it in GitHub Desktop.
Save einblicker/1305862 to your computer and use it in GitHub Desktop.
lazy list monad
(ql:quickload :pipes)
(ql:quickload :cl-cont)
(ql:quickload :cl-monad-macros)
(defpackage :llmonad
(:use :cl :pipes :cl-cont :cl-monad-macros))
(in-package :llmonad)
(defun pipe-tail-no-cache (pipe)
(if (functionp (rest pipe))
(funcall (rest pipe))
(rest pipe)))
(defmacro with-llist-monad (&body body)
`(with-monad ((lambda (x) (make-pipe x +empty-pipe+))
(lambda (pipe fn) (pipe-mappend fn pipe)))
,@body))
(defun pipe-foldl (fn acc pipe)
(if (eq pipe +empty-pipe+)
acc
(pipe-foldl fn
(funcall fn acc (pipe-head pipe))
(pipe-tail-no-cache pipe))))
(defun integers (n)
(make-pipe n (integers (1+ n))))
(defmacro reset (&body body)
`(without-call/cc
(with-call/cc
,@body)))
(defmacro reify (thunk)
`(reset (funcall (lambda (x) (unit x)) ,thunk)))
(defmacro reflect (meaning)
`(let/cc
k
(funcall (lambda (m f) (funcall! m f)) ,meaning k)))
(with-llist-monad
(reify
(let ((x (reflect (integers 1)))
(y (reflect (integers 1))))
(+ x y))))
(defun zeros (n)
(if (zerop n)
+empty-pipe+
(make-pipe 0 (zeros (1- n)))))
(pipe-foldl
#'+
0
(with-llist-monad
(reify
(let* ((zeros (zeros 10000))
(x (reflect zeros))
(y (reflect zeros)))
(+ x y)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment