next up previous
Next: 1.7 バインディング情報に基づく置換 Up: 1 変数を含むパターンとデータのマッチング Previous: 1.5 マッチング関数の定義

1.6 ラムダ式の構造比較への応用例

ラムダ式の構造が同じかどうかを判定する関数へ このパターンマッチング関数を応用することを 考えることにします. 解決方法は,ラムダ式の引数部分の中に含まれる仮引数変数を パターンマッチングにおける変数とすればよいわけです. 仮引数変数を?で始まる変数に置き換え,ラムダ式の本体の中に現れる仮引数 すべてを?で始まるものに置き換えるという方法も考えられるが,前に示した ように,属性リストを使ってマッチング変数であることを指定する方式を用い ると本体の置き換えが必要なくなり,簡単に実現が可能となります.

(defun equal-lambda-exp (a b)
  (let
      ((vars
        (init-matching-variables
         (lambda-variables a)))
       (result (match a b)))
    (clear-matching-variables vars)
    (if (eq 'fail result) nil t)))

(defun lambda-variables (e)
  (remove-if
   #'null
   (mapcar
    #'(lambda (x)
        (cond
         ((symbolp x)
          (if (char=
                (char (symbol-name x) 0)
                #\&)
              nil
              x))
         ((consp x)
          (if (atom (first x))
              (first x)
            (second (first x))))))
    (second e))))
lambda-variablesは,ラムダ式の引数(ラムダリスト) の中の変数のみを拾い集める関数です.

<cl> (lambda-variables
         '(lambda (x y) (list x y)))
(X Y) 
<cl> (lambda-variables
         '(lambda (x &rest args) (list x args)))
(X ARGS) 
<cl> (lambda-variables
         '(lambda (x &key a (b 10)) (list x a b)))
(X A B) 
<cl> (lambda-variables
         '(lambda (&key ((:abc a) 10)) (list a)))
(A)
equal-lambda-expの例は以下のようになります.

<cl> (equal-lambda-exp
         '(lambda (x y) (list x y))
         '(lambda (a b) (list a b)))
T 
<cl> (equal-lambda-exp
         '(lambda (x y) (list x y))
         '(lambda (y) (list y)))
NIL 
<cl> (equal-lambda-exp
         '(lambda (&key x (y 10)) (list x y))
         '(lambda (&key a (b 10)) (list a b)))
T 
<cl> (equal-lambda-exp
         '(lambda () (fib 1))
         '(lambda () (fib 1)))
T

next up previous
Next: 1.7 バインディング情報に基づく置換 Up: 1 変数を含むパターンとデータのマッチング Previous: 1.5 マッチング関数の定義
generated through LaTeX2HTML. M.Inaba 平成18年5月21日