我有一个模式列表,如何将它们转换为匹配函数?
(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
这是文档,我还不太明白,所以也许有人可以帮我举个例子,说明我要做什么。
这里有几件事:
- 您可以链接到CHICKEN 3的文档,它非常古老(当时
match
是核心系统的一部分)。您使用的是CHICKEN 4,我可以从您在顶部执行(use matchable)
的事实中看出,因此文档可能与您使用的可匹配版本不匹配(双关语) - 请考虑更新到鸡5,因为鸡4没有积极开发
- Match是一个宏,它需要能够在编译时分析模式,这意味着你不能传入动态列表(这将在运行时发生)。它根据拾取输入的模式,扩展为使用
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中。