HIRAUCHI Hideyuki
hira****@verys*****
2004年 4月 3日 (土) 15:02:51 JST
これはスバラシイですね。 私も同じようなことがやりたかったので、さっそく使わせてもらいます。 おまけ: メール末尾にgoshにコピペできるよう編集しなおした実行例をつけときます。 --hira (load "hira/smatch.scm") ;ここでmailを読み込む。ファイル名は適当です。 (define my-append (smatch-lambda (( '() ys) ys) (( (x . xs) ys) (cons x (my-append xs ys))))) (define (append-test app) (define ls '()) (print app) (set! ls (app ls '(a))) (set! ls (app ls '(b))) (print ls)) (append-test append) (append-test my-append) ;;;my-appendはこう展開される ;(define my-append ; (lambda #<id 0x102943a0 user::args> ; (let ((#<id 0x10297d40 user::binds> (smatch '( '() ys) args))) ; (if binds ; (apply (lambda (ys) ys) (map cadr binds)) ; (let ((#<id 0x1029b1a0 user::binds> (smatch '((x . xs) ys) args))) ; (if binds ; (apply (lambda (x xs ys) (cons x (my-append xs ys))) ; (map cadr binds)) ; (error "Wrong arguments to SMATCH-LAMBDA" args))))))) ;; 例 ;長さが3で、第一要素と第三要素が等しいリストにマッチ (smatch '(a b a) '((c d) 2 (c d))) ;=> ((a (c d)) (b 2)) ;長さが3で、第一要素が1、第三要素がシンボルcであるリストにマッチ (smatch '(1 b 'c) '(1 2 c)) ;=> ((b 2)) (smatch '(1 a) '(1)) ;=> #f ;長さが2で、第二要素が長さが2でcar部が第一要素に等しいリスト、 ;であるリストにマッチ (smatch '(a (a b)) '(1 (1 2))) ;=> ((a 1) (b 2)) ;長さが3で、第二要素が長さが3で第三要素が'(2)であるベクター、 ;であるリストにマッチ (smatch '(a #(b c '(2)) d) '(1 #(2 3 (2)) 4)) ;=> ((a 1) (b 2) (c 3) (d 4)) ;長さが3で、第一要素が"ab" 第三要素がシンボルa, b, cからなるベクター、 ;であるリストにマッチ (smatch '("ab" b '#(a b c)) '("ab" 2 #(a b c))) ;=> ((b 2)) ;何にでもマッチ (smatch 'args '(a b c)) ;=> ((args (a b c))) ;長さが1以上のリストにマッチ (smatch '(a . b) '(1 2 3)) ;=> ((a 1) (b (2 3))) ;空リストにマッチ (smatch '() '()) ;=> ()