我有一个模式列表,如何将它们转换为匹配功能?
(use matchable)
(define prop '(and (#t #t) #t))
(define patt '(and (X Y) Z)) ;;here is the pattern example
(match prop [('and (X Y) Z) (list X Y Z)])) ;;(#t #t #t) this works
(match prop [patt (list X Y Z)])) ;;anything matches the pattern???
最后一次匹配不起作用,我所有的变量都是符号,我不确定它们在匹配表达式中是什么
https://wiki.call-cc.org/man/3/Pattern%20matching
这是文档,我还不太了解,所以也许有人可以帮我举一个我想做的事的例子。
答案 0 :(得分:3)
这里有几件事:
match
是核心系统的一部分)。您正在使用CHICKEN 4,从您在顶部进行(use matchable)
的事实中可以看出,所以文档可能与您使用的可匹配版本不匹配(双关)。car
,cdr
等扩展为表达式。如果在编译时未知模式,则无法执行此操作。如果您确实必须动态传递模式,则可以执行以下操作:
(use matchable)
;; Define patt to be available at the macro expansion level
(define-for-syntax patt '('and (X Y) Z))
;; Make a macro that *expands* to the desired match form
(define-syntax match-patt
(ir-macro-transformer
(lambda (e i c)
`(match ,(cadr e)
(,(i patt) (list ,(i 'X) ,(i 'Y) ,(i 'Z)))))))
;; Actually call the macro to generate the expression
(define prop '(and (#t #t) #t))
(match-patt prop)
当然,只有在编译时知道模式的情况下,这仍然可以工作,因此除非您正在做一些非常有趣的事情,例如在编译时从文件或其他内容读取模式,否则这实际上不会给您带来任何好处
在Lisp(或Scheme)中进行编程时,必须始终记住要在扩展过程的哪个级别进行编程。通常有两个级别:编译时和运行时。宏在编译时扩展为代码,因此您永远无法使宏对运行时可用的信息进行操作。
当然,您也可以使用eval
生成匹配表达式。评估后的代码又分两个阶段运行:首先进行宏扩展,然后运行代码。但是,由于您是在运行的程序中完成所有操作,因此可以将在运行时确定的表达式插入eval。