fold-right のこと、すっかり勘違いしてた。あいつはああ見えても雨の日にずぶ濡れになった子犬を抱いて「へへっ…… おめえもh

;; fold-left
(define (fold-left op initial sequence)
  (define (iter result rest)
    (if (null? rest)
        result
        (iter (op result (car rest)) ;; <- ここを
              (cdr rest))))
  (iter initial sequence))

;; fold-right
(define (fold-right op initial sequence)
  (define (iter result rest)
    (if (null? rest)
        result
        (iter (op (car rest) result) ;; <- こうすればいいと思ってた
              (cdr rest))))
  (iter initial sequence))

これだとたとえばこんなんは

(fold-left / 1 '(1 2 3))
;; => 0.16666666666666666

(fold-right / 1 '(1 2 3))
;; => 1.5

こうなる。一見あってるっぽい。しかしこんなんは

(fold-left list '() '(1 2 3))
;; => (((() 1) 2) 3)

(fold-right list '() '(1 2 3))
;; => (3 (2 (1 ())))

;; これが正解
;; => (1 (2 (3 ())))

こうなる。明らかに違うんだけど、これで合ってると思っていた。阿呆だ。

;; fold-right
(define (fold-right op initial sequence)
  (define (iter result rest)
    (if (null? rest)
        result
        (op (car rest)
            (iter result (cdr rest)))))
  (iter initial sequence))

正しくはこうだった。ちなみにpyてょnで reduce を使ってむりやり書くとこうなる。

l=[1, 2, 3]

reduce(lambda x,y: x/y, l, 1.0)
# => 0.16666666666666666

reduce(lambda x,y: y/x, (l[-(i+1)] for i in range(len(l))), 1.0)
# or
reduce(lambda x,y: y/x, l.reverse() or l, 1.0)
# => 1.5

reduce(lambda x,y: [x, y], l, [])
# => [[[[], 1], 2], 3]

reduce(lambda x,y: [y, x], (l[-(i+1)] for i in range(len(l))), [])
# or
reduce(lambda x,y: [y, x], l.reverse() or l, [])
# => [1, [2, [3, []]]]

l.reverse() or l という書き方がだんだん普通に思えてきました。