Most direct usage of flatmap

Viewed 162

I've written a map and a flatmap function, and I'm trying to figure out the best way to see how the flatmap function works as a standalone. Here are my two definitions:

(define (map function lst)
  (if (null? lst)
      ; if we have reached the end of the list, return an empty list
      ; this essentially terminates the list that we are adding below with the cons
      nil
      ; we do a cons -- with the scalar produced by the function call on the current element
      ;                 and the list proceduced by passing the rest of the elements again to the map function
     (cons (function (car lst)) (map function (cdr lst)))))
(define (flatmap function lst)
  (if (null? lst)
      nil
      ; really the only difference here is we do an append instead of a cons
      (append (function (car lst)) (flatmap function (cdr lst)))))

And to call map is quite easy, I just pass it a function that accepts a single argument (list element):

(map (lambda (x) (* x x)) '(1 2 3 4 5))
; (1 4 9 16 25)

However, I'm having a hard time coming up with a sample input/function that I can pass directly to the flatmap function to see how it works. What would be an example or two that would demonstrate how it works directly?

2 Answers

Any function that accepts a single argument and returns a list will do. Here's a variation of the function you used to demonstrate map.

(flatmap (lambda (x) (list x (* x x))) '(1 2 3 4 5))
; (1 1 2 4 3 9 4 16 5 25)

Here are a few examples:

;;; flattening a list by one-level
(flatmap (lambda (p) p) '((1 2 3) (4 5 6)))
;(1 2 3 4 5 6)
(flatmap (lambda (p) p) '((1 2 (3 4) 5) (6 7 8)))
; (1 2 (3 4) 5 6 7 8)
;;; Map-and-flatten a list at once
(flatmap
    (lambda (p) (cons (* 2 (car p)) 
                      (list (* 2(cadr p))) )) 
    '((1 2) (3 4)))
; (2 4 6 8)
; Or could be done with a combination of the two which reads more simply:
(map (lambda (x) (* x 2)) 
     (flatmap (lambda (p) p) '((1 2) (3 4))))
; (2 4 6 8)
;; Possible to do something like (flatmap (lambda (x) (map... ?) to accomplish same?

Though most of the above just use the lambda (p) p identity which seems pretty useless overall I'm guessing...

And maybe an actually useful one to recursively flatten a list:

(define (flat lst)
  (flatmap (lambda (x) (if (pair? x) (flat x) (list x))) lst))

(flat '(1 2 3 (1 (2 3 (5 5 5) 4) 3)))
; (1 2 3 1 2 3 5 5 5 4 3)
Related