如何在Racket中匹配构造模式?

时间:2018-03-25 05:44:21

标签: scheme racket quote

我知道我们可以使用Racket中的quasiquote模式进行模式匹配。例如:

> (match '(3) [`(,l) l])
3

但是,我不确定是否可以使用预先存在的模式(例如

)获得相同的结果
> (define pattern '`(,l))
> pattern
'`(,l)

如何将这样的pattern注入match子句?

2 个答案:

答案 0 :(得分:2)

match是一个宏。它使用其参数,即模式,来自之前运行时。如果您检查宏步进器(match '(3) [`(,l) l])变为:

(let ([temp1 '(3)])
  (define (fail2) 
    (match:error temp1 (syntax-srclocs (quote-syntax srcloc)) 'match))
  (cond
   [(pair? temp1)
    (let ([unsafe-car4 (unsafe-car temp1)] [unsafe-cdr5 (unsafe-cdr temp1)])
      (cond
       [(null? unsafe-cdr5)
        (syntax-parameterize
         ([fail (make-rename-transformer (quote-syntax fail2))])
         (let ([l unsafe-car4]) (let () l)))]
       [else (fail2)]))]
   [else (fail2)]))

如果您使用变量pattern代替`(,1),它只会认为您的模式与整个参数相匹配。正如(match '(3) [pattern l])

的扩展所示
(let ([temp1 '(3)])
  (define (fail2) 
    (match:error temp1 (syntax-srclocs (quote-syntax srcloc)) 'match))
  (syntax-parameterize ([fail (make-rename-transformer (quote-syntax fail2))])
    (let ([pattern temp1]) (let () l))))

您的变量pattern在此之后很久就不存在,因此match无法采用动态模式。您需要将模式逻辑移动到宏扩展时间,如果原因是您要在许多模式上进行抽象,但仍然可以在没有输入的情况下进行计算。

如果您需要输入模式,则无法以这种方式使用match。也许你需要在运行时制作类似的东西。

由于该示例非常基础,我不知道您要实现的目标。我想这可能是XY problem

答案 1 :(得分:0)

虽然我不确定你想要完成什么,但我想指出你可以定义match expanders。请记住,与匹配一样,这些存在于编译而不是运行时。