Custom map function - how does it work?

后端 未结 1 2000
面向向阳花
面向向阳花 2021-01-25 05:55

I apologize for the unclear topic title.

I have this function in Scheme which is a custom implementation of the map function. It works fine

1条回答
  •  走了就别回头了
    2021-01-25 06:58

    Here's one way to understand the procedure:

    • The iter helper is the same as map, but operating on a single list.
    • The map-rec helper generalizes iter, working for a list of lists, stopping when at least one of the lists is empty
    • This part: (apply proc (iter car ls0)) applies the procedure on the first element of each list; the call to iter creates a list of the car part of the lists
    • And this part: (map-rec proc (iter cdr ls0)) simultaneously advances the recursion over all the lists; the call to iter creates a list of the cdr part of the lists

    Perhaps renaming the procedures will make things clear. Here's a completely equivalent implementation, making explicit the fact that map-one operates on a single list and map-many operates on a list of lists:

    (define (map-one proc lst)  ; previously known as `iter`
      (if (null? lst)
          '()
          (cons (proc (car lst))
                (map-one proc (cdr lst)))))
    
    (define (map-many proc lst) ; previously known as `map-rec`
      (if (memq '() lst)
          '()
          (cons (apply proc (map-one car lst))
                (map-many proc (map-one cdr lst)))))
    
    (define (my-map proc . lst) ; variadic version of `map-many`
      (map-many proc lst))
    

    It works just like the original my-map:

    (my-map + '(1 2 3) '(4 5 6) '(7 8 9))
    => '(12 15 18)
    

    And you can check that map-one is really a map that works on a single list:

    (map-one (lambda (x) (* x x))
             '(1 2 3 4 5))
    => '(1 4 9 16 25)
    

    See the effect of (map-one car lst) on a list of lists:

    (map-one car '((1 4 5) (2 6 7) (3 8 9)))
    => '(1 2 3)
    

    Likewise, see how (map-one cdr lst) works:

    (map-one cdr '((1 4 5) (2 6 7) (3 8 9)))
    => '((4 5) (6 7) (8 9))
    

    0 讨论(0)
提交回复
热议问题