Common Lisp - 模式匹配
Common Lisp - Pattern Matching
我正在尝试编写一个函数来比较 Common Lisp 中的两个列表。
符号“&”表示任何元素序列,符号“$”表示任何单个元素。
(defun match (filter data)
(cond
((atom filter) (eq filter data))
((atom data) NIL)
((eq (car filter) '|$|)
(match (cdr filter) (cdr data)))
((eq (car filter) '|&|)
(cond
((match (cdr filter) data))
(data (match filter (cdr data)))))
((match (car filter) (car data))
(match (cdr filter) (cdr data)))))
效果很好:
(match '(a b c) '(a b c)) ; => T
(match '(a $ c) '(a b c)) ; => T
(match '(a ff c) '(a b c)) ; => NIL
(match '(a & c) '(a z b c)) ; => T
我想添加一个新的过滤器(带有 % 符号),它允许在不同的可能元素之间进行选择,例如
(match '(a %(b 1) c) '(a b c)) ; => T
(match '(a %(b 1) c) '(a 1 c)) ; => T
(match '(a %(b 1) c) '(a z c)) ; => NIL
您必须尝试 % 之后的子列表中的所有元素,看看是否有任何元素与过滤器的其余部分相匹配:
(defun match (filter data)
(cond
((atom filter) (eq filter data))
((atom data) NIL)
((eq (car filter) '|$|)
(match (cdr filter) (cdr data)))
((eq (car filter) '|&|)
(cond
((match (cdr filter) data))
(data (match filter (cdr data)))))
((eq (car filter) '|%|)
(some #'(lambda (f) (match (cons f (cddr filter)) data)) (cadr filter)) )
((match (car filter) (car data))
(match (cdr filter) (cdr data)))))
您还应该添加一些检查步骤以确保过滤器的格式正确,即 % 之后的元素是列表等...
我正在尝试编写一个函数来比较 Common Lisp 中的两个列表。
符号“&”表示任何元素序列,符号“$”表示任何单个元素。
(defun match (filter data)
(cond
((atom filter) (eq filter data))
((atom data) NIL)
((eq (car filter) '|$|)
(match (cdr filter) (cdr data)))
((eq (car filter) '|&|)
(cond
((match (cdr filter) data))
(data (match filter (cdr data)))))
((match (car filter) (car data))
(match (cdr filter) (cdr data)))))
效果很好:
(match '(a b c) '(a b c)) ; => T
(match '(a $ c) '(a b c)) ; => T
(match '(a ff c) '(a b c)) ; => NIL
(match '(a & c) '(a z b c)) ; => T
我想添加一个新的过滤器(带有 % 符号),它允许在不同的可能元素之间进行选择,例如
(match '(a %(b 1) c) '(a b c)) ; => T
(match '(a %(b 1) c) '(a 1 c)) ; => T
(match '(a %(b 1) c) '(a z c)) ; => NIL
您必须尝试 % 之后的子列表中的所有元素,看看是否有任何元素与过滤器的其余部分相匹配:
(defun match (filter data)
(cond
((atom filter) (eq filter data))
((atom data) NIL)
((eq (car filter) '|$|)
(match (cdr filter) (cdr data)))
((eq (car filter) '|&|)
(cond
((match (cdr filter) data))
(data (match filter (cdr data)))))
((eq (car filter) '|%|)
(some #'(lambda (f) (match (cons f (cddr filter)) data)) (cadr filter)) )
((match (car filter) (car data))
(match (cdr filter) (cdr data)))))
您还应该添加一些检查步骤以确保过滤器的格式正确,即 % 之后的元素是列表等...