💾 Archived View for tozip.chickenkiller.com › 2022-06-24-guile-foldr.gmi captured on 2023-06-16 at 16:13:42. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2022-07-16)
-=-=-=-=-=-=-
Created 2022-06-24
I just wanted to try out my understanding of foldr in Scheme.
The test is to take a list of ints and return another list of ints. The resultant should contain only even integers, and they should be duplicated in the output.
Here's an implementation in Guile:
(use-modules (srfi srfi-1)) (define foldr fold-right) (display (foldr (lambda (a b) (if (even? a) `(,a ,a ,@b) b)) '() '(1 2 3 4 5 6)))
Running it produces the expected output:
(2 2 4 4 6 6)
Let's do a little abstraction. Instead of knowing what the list has been built up to so far, let's define the notion of a collector. To be specific, define the function collect as follows:
(define (collect lst fn) (foldr (lambda (el built) (define result built) (define (col x) (set! result (cons x result))) (fn el col) result) '() lst))
It builds up its own notion of the result. It creates a function "col", to collect (perhaps I could should call it "emit") values. "fn" is a function that takes an element in the list, and the function "col", which performs the collecting.
So here's how you'd use it:
(display (collect '(1 2 3 4 5 6 7 8) (lambda (x col) (when (even? x) (col x) (col x)))))
It produces the required result:
(2 2 4 4 6 6 8 8)
Perhaps this might be considered as to delving into the bag of tricks, and it is an unnecessary abstraction. It does have the advantage though, that you can collect anything and nothing, and the called function itself does not have to keep track of what's being built.
Just something to think about.