git.fiddlerwoaroof.com
Raw Blame History
(defpackage :fwoar.recursion-schemes
  (:use :cl)
  (:export ))
(in-package :fwoar.recursion-schemes)

(defun cdr* (cons)
  (funcall (cdr cons)))

;; cata :: (a -> b -> b) -> b -> [a] -> b
(defun cata (fun init as)
  (if (null as)
      init
      (funcall fun
               (car as)
               (cata fun init
                     (cdr as)))))

;; para :: (a -> [a] -> b -> b) -> b -> [a] -> b
(defun para (fun init as)
  (if (null as)
      init
      (funcall fun (car as) (cdr as)
               (para fun init (cdr as)))))

;; ana :: (v -> (a, () -> b)) -> b -> [a]
(defun ana (fun init)
  (destructuring-bind (a init*)
      (funcall fun init)
    (cons a (lambda () (ana fun init*)))))

;; ana :: (v -> Maybe (a, b)) -> b -> [a]
(defun ana* (fun init)
  (let ((v (funcall fun init)))
    (when v
      (cons (car v)
            (ana* fun (cadr v))))))

;; hylo  :: (a -> c -> c) -> c -> (b -> Maybe (a, b)) -> b -> c
(defun hylo (reducer reducer-init generator generator-seed)
  (flet ((partial-ana (init)
           (ana* generator init)))
    (cata reducer reducer-init
          (partial-ana generator-seed))))

;; zygo (a -> b -> b) -> (a -> b -> c -> c) -> b -> c -> [a] -> c
(defun zygo (fold-1 fold-2 fold-1-init fold-2-init as)
  (second
   (cata (fw.lu:destructuring-lambda (x (p q))
           (list (funcall fold-1 x p)
                 (funcall fold-2 x p q)))
         (list fold-1-init fold-2-init)
         as)))