可匹配的列表到模式转换(鸡肉方案)

时间:2019-02-06 23:25:52

标签: pattern-matching scheme chicken-scheme

我有一个模式列表,如何将它们转换为匹配功能?

(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

这是文档,我还不太了解,所以也许有人可以帮我举一个我想做的事的例子。

1 个答案:

答案 0 :(得分:3)

这里有几件事:

  • 您链接到CHICKEN 3的文档,该文档非常古老(当时match是核心系统的一部分)。您正在使用CHICKEN 4,从您在顶部进行(use matchable)的事实中可以看出,所以文档可能与您使用的可匹配版本不匹配(双关)。
  • 由于未积极开发CHICKEN 4,请考虑更新到CHICKEN 5。
  • Match是一个宏,需要能够在编译时分析模式,这意味着您无法传递动态列表(在运行时会发生这种情况)。根据将输入分开的模式,它使用carcdr等扩展为表达式。如果在编译时未知模式,则无法执行此操作。

如果您确实必须动态传递模式,则可以执行以下操作:

(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。