git.fiddlerwoaroof.com
Browse code

refactor(transducers): foldling -> reduce-generic

fiddlerwoaroof authored on 19/12/2020 06:31:54
Showing 1 changed files
... ...
@@ -78,21 +78,30 @@
78 78
 (defgeneric init (it))
79 79
 (defgeneric stepper (it))
80 80
 
81
-(defgeneric foldling (seq func init)
81
+(defgeneric reduce-generic (seq func init)
82 82
   (:method ((seq sequence) (func function) init)
83 83
     (reduce func seq :initial-value init))
84 84
   (:method ((seq sequence) (func symbol) init)
85
-    (reduce func seq :initial-value init)))
85
+    (reduce func seq :initial-value init))
86
+  (:method (seq (func symbol) init)
87
+    (foldling seq (symbol-function func) init))
88
+  (:method ((seq hash-table) (func function) init)
89
+    (let ((acc init))
90
+      (maphash (lambda (k v)
91
+                 (setf acc (funcall func acc (list k v))))
92
+               seq)
93
+      acc)))
94
+
86 95
 (defun transduce (xf build seq)
87 96
   (unwrap build
88 97
           (catch 'done
89
-            (foldling seq
90
-                      (funcall xf (stepper build))
91
-                      (init build)))))
98
+            (reduce-generic seq
99
+                            (funcall xf (stepper build))
100
+                            (init build)))))
92 101
 
93 102
 (defclass lazy-sequence ()
94 103
   ((%next :initarg :next :reader next)))
95
-(defmethod foldling ((seq lazy-sequence) (func function) init)
104
+(defmethod reduce-generic ((seq lazy-sequence) (func function) init)
96 105
   (let ((next (next seq)))
97 106
     (loop for next-val = (funcall next)
98 107
           for acc = init then next-acc