sicplite #7 にいってきた
- 超ムーミン
- 口がlite
- でも,やるときにはやる
- fold で書くとか
- 個人的に Gauche の fold の引数と Haskell の foldl の引数の順序が違う気がする(未検証
- accumulator って,fold-left だよね
- fold って,inject?
なので,こんな感じに書ける
(define (reverse xs) (fold cons (list) xs)) (define (deep-reverse tree) (fold (lambda (x i) (cons (if (pair? x) (deep-reverse x) x) i)) (list) tree))
fold-left と fold-right は,展開したのを考えるとわかりやすいと自分では思っている.
(fold-left f i [list a b c]) ; => (f c (f b (f a i))) ; 展開した形 (fold-right f r [list a b c]) ; => (f a (f b (f c r))) ; 展開した形
引数の作用順が違う.
#!/usr/bin/env gosh (fold (lambda (x i) (cons x i)) (list) (list 1 2 3)) ; => (3 2 1) (fold-right (lambda (x r) (cons x r)) (list) (list 1 2 3)) ; => (1 2 3)
引数の順序をわかりやすくするために,わざとlambda 式で書いてある.
ということで,Ruby の inject は,fold-left ってことで
irb(main):001:0> [1,2,3].inject([]) {|i,x| i << x} => [1, 2, 3]
参考