■
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 という書き方がだんだん普通に思えてきました。