deepmapってこんな感じでいいのかな?
(define (deepmap p f seq) (apply (lambda (x y) (let ((fx (f x)) (fy (f y))) (if (eqv? fx (p fx fy)) x y))) seq)) (deepmap min car '((3 p) (2 q))) ;; => (2 q)
applyじゃだめだった。
引数の数が3つの時、失敗する。
(foldみたいな感覚でいたけど違ったみたい)
(そう言えば、(+ 1 2 3) => 6だ。 (+ (+ 1 2) 3)に変換されるわけじゃないのか…)
(deepmap min car '((3 p) (2 q) (4 s))) 4:user> *** ERROR: wrong number of arguments for #<closure (deepmap deepmap)> (required 2, got 3)
やっぱり、foldを普通に使うしかないみたいです><。
(define (deepmap p f seq) (fold (lambda (x y) (let ((fx (f x)) (fy (f y))) (if (eqv? fx (p fx fy)) x y))) (car seq) (cdr seq)))
eq?じゃなくてeqv?な理由
eq?は比較する対象が文字だったり数値だったりした時の動作が未定義だからみたい。
-- Function: eq? obj1 obj2 [R5RS] 最も高速で、細かい区別ができる述語です。 OBJ1とOBJ2がアロケートされる同じ型のオブジェクトで、 かつ両者がメモリ上の全く同じ場所を占めるオブジェクトを指している場合に `#t'を返します。また、OBJ1とOBJ2がともに `#f', `#t'あるいは`()'である場合も`#t'を返します。 ポインタ比較と考えても良いでしょう。 OBJ1とOBJ2がともに文字、あるいは数値であった場合の振るまいは Schemeの標準では定められていません。
でも何でこのような関数をdeepmapってつけようと思ったんだろ?
普通deepmapって言ったら、こんな感じのものを想像するような気がする。
(define (deep-map f tree) (map (lambda (x) (if (list? x) (deep-map f x) (f x))) tree)) (deep-map (lambda (x) (* x x x)) '(1 (2 (3 4) 5) 6)) ;; => (1 (8 (27 64) 125) 216)