Browse code
feat: allow over to accept multiple functions and compose them
Edward Langley authored on 13/04/2023 16:29:22
Showing 2 changed files
Showing 2 changed files
... | ... |
@@ -291,10 +291,29 @@ |
291 | 291 |
seq |
292 | 292 |
:initial-value ())))) |
293 | 293 |
|
294 |
-(defun over (fun &key (result-type 'list)) |
|
295 |
- (let ((fun (functionalize fun))) |
|
296 |
- (lambda (seq) |
|
297 |
- (map result-type fun seq)))) |
|
294 |
+(defun over (fun &rest funs) |
|
295 |
+ (let* ((fun (functionalize fun)) |
|
296 |
+ (rt-pos (position :result-type funs)) |
|
297 |
+ (result-type (cond |
|
298 |
+ ((null rt-pos) 'list) |
|
299 |
+ ((>= (1+ rt-pos) |
|
300 |
+ (length funs)) |
|
301 |
+ (error "invalid result-type")) |
|
302 |
+ (t |
|
303 |
+ (elt funs (1+ rt-pos))))) |
|
304 |
+ (funs (if rt-pos |
|
305 |
+ (append (mapcar #'functionalize |
|
306 |
+ (subseq funs 0 rt-pos)) |
|
307 |
+ (mapcar #'functionalize |
|
308 |
+ (subseq funs (+ rt-pos 2)))) |
|
309 |
+ (mapcar #'functionalize funs))) |
|
310 |
+ (combined-fun (if funs |
|
311 |
+ (apply #'alexandria:compose fun funs) |
|
312 |
+ fun))) |
|
313 |
+ (lambda (seq &rest seqs) |
|
314 |
+ (if seqs |
|
315 |
+ (apply #'map result-type combined-fun seq seqs) |
|
316 |
+ (map result-type combined-fun seq))))) |
|
298 | 317 |
|
299 | 318 |
(defun denest (&key (result-type 'list)) |
300 | 319 |
(lambda (seq) |
... | ... |
@@ -250,6 +250,12 @@ |
250 | 250 |
(5am:is (equalp #(1 2 3) |
251 | 251 |
(funcall (data-lens:over '1+ :result-type 'vector) |
252 | 252 |
'(0 1 2)))) |
253 |
+ (5am:is (equalp #(2 3 4) |
|
254 |
+ (funcall (data-lens:over '1+ :result-type 'vector '1+) |
|
255 |
+ '(0 1 2)))) |
|
256 |
+ (5am:is (equalp #(2 3 4) |
|
257 |
+ (funcall (data-lens:over '1+ '1+ :result-type 'vector) |
|
258 |
+ '(0 1 2)))) |
|
253 | 259 |
(5am:is (equalp #(1 2 3) |
254 | 260 |
(funcall (data-lens:over '1+ :result-type 'vector) |
255 | 261 |
#(0 1 2))))) |