Skip to content

Instantly share code, notes, and snippets.

@turanct
Last active August 29, 2015 14:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save turanct/90fc232a19298d7b9723 to your computer and use it in GitHub Desktop.
Save turanct/90fc232a19298d7b9723 to your computer and use it in GitHub Desktop.
Folds are awesome abstractions over recursive function calls
; As seen in my previous gist about lisp list-functions
; (https://gist.github.com/turanct/e84be7f355e255c2c1b5)
; all list functions can be created relatively easy from
; a few function calls, using recursive functions.
; As the pattern for those functions is almost always the same,
; that can be abstracted out. The way we do this is using folds.
;
; Folds take a function, an initial value (or carry), and a
; list, and they use the function to combine the carry with the
; next element of the list. When the fold iterated over the
; whole list, one value is returned.
; left fold
(define (my-fold-left fn initial l)
(if (null? l)
initial
(my-fold-left fn (fn (car l) initial) (cdr l))))
; right fold
(define (my-fold-right fn initial l)
(if (null? l)
initial
(fn (car l) (my-fold-right fn initial (cdr l)))))
(define (my-length l)
(my-fold-right
(lambda (_ x) (+ 1 x))
0
l))
(define (my-append la lb)
(my-fold-right
(lambda (element list) (cons element list))
lb
la))
(define (my-reverse l)
(my-fold-left
(lambda (element list) (cons element list))
'()
l))
(define (my-map fn l)
(my-fold-right
(lambda (element list) (cons (fn element) list))
'()
l))
(define (my-filter fn l)
(my-fold-right
(lambda (element list)
(if (fn element)
(cons element list)
list))
'()
l))
(define (my-reduce fn l initial)
(my-fold-right
(lambda (element list) (fn list element))
initial
l))
(define (my-zip la lb)
(fold
(lambda (ea eb list) (cons (cons ea eb) list))
'()
la lb))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment