2015/10/21

schemeでmapを書いてみた

SICPの問題 2.37をやろうとしたところ,この本で定義した一つのリストのみに対応したmapではなく
複数のリストに対応したmapが必要だったので自分で書いてみました.
 

(define (foldr op init lst)
  (if (null? lst)
      init
      (op (car lst)
          (foldr op init (cdr lst)))))


(define (map op . lst)
  (define (map1 op lst)
    (foldr (lambda (x y) (cons (op x) y)) '() lst))
  (cond ((null? lst) '())
        ((null? (cdr lst)) (map1 op (car lst)))
        (else (let loop ((rest lst))
                (cond ((null? rest) '())
                      ((foldr (lambda (x y) (or (null? x) y)) #f rest)
                       (loop (filter (lambda (x) (not (null? x))) rest)))
                      (else (cons (apply op (map1 car rest))
                                  (loop (map cdr rest)))))))))
gosh> (map + '(1 2 3) '(4 5 6))
(5 7 9)

うまく動いてくれてるようです.
可変長引数を省略した時にはrestに空リストが入るので(null? rest)で分岐することにしました.


© 2022 wat-aro