Some new ways implementing fold, scan and unfold F# functions in LISP.
EDIT: new definitions so that the functions require a *quoted* function as argument (as others 'higher order' LISP functions as apply, mapcar, ...)
gc:fold
;|
gc:fold
Returns the final state of an accumulator which initial state is changed
by applying a function to the accumulator and each item of a list.
Arguments
fun: a function (lambda or defun) which takes a state and a list item as arguments
and returns the modified state
acc : accumulator initial state
lst ; list
|;
(defun gc:fold (fun acc lst)
(foreach n lst (setq acc ((eval fun) acc n)))
)
gc:scan
;|
gc:scan
Returns the list of all intermediates states mor final state of an accumulator
which initial state is changed by applying a function to the accumulator and
each item of a list.
Arguments
fun: a function (lambda or defun) which takes a state and a list item as arguments
and returns the modified state
acc : accumulator initial state
lst ; list
|;
(defun gc:scan (fun acc lst)
(cons acc (mapcar '(lambda (x) (setq acc ((eval fun) acc x))) lst))
)
gc:unfold
;|
gc:unfold
Generates a list from a calculation function which takes a state
and modify it to product the next item.
Arguments
fun: a function (lambda or defun) which takes a state as argument and
returns a list of type: (result next_state) or nil (requiered stop condition).
state: the initial state
|;
(defun gc:unfold (fun state)
((lambda (r)
(if r
(cons (car r) (gc:unfold fun (cadr r)))
)
)
((eval fun) state)
)
)
(gc:fold '(lambda (a l) (mapcar '+ (cons 0 a) (append a '(0)))) '(1) '(1 2 3 4 5))
returns: (1 5 10 10 5 1)
(gc:scan '(lambda (a l) (mapcar '+ (cons 0 a) (append a '(0)))) '(1) '(1 2 3 4 5))
returns: ((1) (1 1) (1 2 1) (1 3 3 1) (1 4 6 4 1) (1 5 10 10 5 1))
(gc:unfold '(lambda (a)
(if (<= (length a) 6)
(list a (mapcar '+ (cons 0 a) (append a '(0))))
)
)
'(1)
)
returns: ((1) (1 1) (1 2 1) (1 3 3 1) (1 4 6 4 1) (1 5 10 10 5 1))