SICP Lite #7

いろいろと Lite な SICP Lite に行ってきた.
http://atnd.org/events/1858


とりあえず俺は fold のことについて書かなければならないと思うので,思考過程みたいなものを書いてみる.
問題2.27.
まず deep-reverse の前に普通の reverse をどう書くかを考えた.
空リストに対して先頭から cons していけばいいなぁと思いながら

(define (reverse lst)
  (fold cons () lst))

こう書ける.
あとはこの cons のところを工夫して,ペアだったら再帰的に deep-reverse してやればいいので

(define (deep-reverse lst)
  (fold (lambda (a b) (if (pair? a) (cons (deep-reverse a) b) (cons a b))) () lst))

こうなる.
あとまぁこれをこのようにほとんど改行せずに書いたら若干驚かれたんですが,たぶん俺がまだプログラムをS式として見れてないからかなぁと思います.
普通はこんなかんじに改行&インデントするらしい.

(define (deep-reverse lst)
  (fold (lambda (a b)
          (if (pair? a)
            (cons (deep-reverse a) b)
            (cons a b)))
        ()
        lst))

どうも Haskell が抜けなくて,実際には

deepReverse = foldl (\a b -> if pair b then deepReverse b:a else b:a) []

みたいなのが頭の中に浮かんでる.*1
あと俺はこのへんに書いたように fold はかなり重要な関数だと考えているので,最初に fold の発想が出てくるんだと思います.
http://d.hatena.ne.jp/eagletmt/20091018/1255876019


どうでもいいけど SchemeHaskell で fold に渡す関数の引数の順番が違ってややこしいですね.

*1:実際には pair なんて関数はないし,そもそも型の都合でこんな関数は書けませんが