【发布时间】:2021-11-07 18:50:17
【问题描述】:
如果我有像(structure-type-name field1-pattern (app some-function pattern-with-variables-a-b) (app some-function pattern-with-variables-c-d)) 这样的模式,我可以使用什么来代替为后面的 2 个字段重复大量代码以仍然有 a、b、c 和 d 绑定?或者,我也会对分别包含 `(,a ,c) 和 `(,b ,d) 列表的 2 个绑定变量感到满意。
编辑
#lang racket
(struct my-struct (field1 field2 field3) #:transparent)
(define s (my-struct '(3 4) '(6 5) '(7 8)))
(match s [(my-struct `(,x ,y)
(app (curryr sort <) `(,lo1 ,hi1))
(app (curryr sort <) `(,lo2 ,hi2)))
(- (* x lo1 lo2) (* y hi1 hi2) (expt lo1 hi2))])
(match s [(app struct->vector
(vector 'struct:my-struct p (app (curryr sort <) `(,lo ,hi)) ...))
; The following line is long and the computation artificial, but just for the sake of an example.
; However, imagine my-struct having more fields.
(apply - `(,@(map (curry apply *) (map cons p `(,lo ,hi))) ,(expt (car lo) (cadr hi))))])
(match s [(app (compose vector->list struct->vector)
(list 'struct:my-struct p (app (curryr sort <) `(,lo ,hi)) ...))
(apply - `(,@(map (curry apply *) (map cons p `(,lo ,hi))) ,(expt (car lo) (cadr hi))))])
(require racket/struct) ; provides struct->list
(match s [(? my-struct?
(app struct->list
(list p (app (curryr sort <) `(,lo ,hi)) ...)))
(apply - `(,@(map (curry apply *) (map cons p `(,lo ,hi))) ,(expt (car lo) (cadr hi))))])
【问题讨论】:
-
我想出了一个解决方案,使用额外的
app和struct->vector(或struct->list,尽管奇怪的是 DrRacket 并没有默认提供它,尽管它位于球拍参考)然后(vector 'struct:structure-type-name field1-pattern (app some-function pattern-with-variables-a-b) ...)。但这很冗长。我想还有更好的方法。 -
也许有准报价?还是一个宏(最好在本地定义,类似于
lambda的匿名函数,但在语法上)? -
你能提供一个具体的例子吗?你想让它看起来像什么?目前的代码是什么样的?
标签: macros pattern-matching racket