用于重命名序列函数的宏

时间:2016-08-20 03:36:18

标签: scheme racket

我可以创建一个宏,以便用sequence-来调用s-个函数吗?因此,我应该能够写s-lengths-filters-map而不是sequence-lengthsequence-filtersequence-map。感谢。

2 个答案:

答案 0 :(得分:3)

您可以使用racket/require中的filtered-in来执行此类转换。这是一个简单的例子:

#lang racket

(require racket/require
         (filtered-in (λ (name) (regexp-replace #rx"^sequence-" name "s-"))
                      racket/sequence))

(s-ref '(1 2 3) 1)

如果您发现自己经常使用此类内容,那么编写一个扩展为filtered-in的{​​{3}}并不会太难:

#lang racket

(require (for-syntax racket/require-transform
                     syntax/parse)
         racket/require)

(define-syntax reprefix-in
  (make-require-transformer
   (syntax-parser
     [(_ original-prefix:id new-prefix:id require-spec:expr ...)
      #:with replacer (string-append "^" (regexp-quote (symbol->string (syntax-e #'original-prefix))))
      #:with replacement (symbol->string (syntax-e #'new-prefix))
      (expand-import #'(filtered-in (λ (name) (regexp-replace (regexp 'replacer) name 'replacement))
                                    (combine-in require-spec ...)))])))

然后你可以像这样使用它:

(require (reprefix-in sequence- s- racket/sequence))
(s-ref '(1 2 3) 1)

答案 1 :(得分:1)

是的。对于诡计多端的水平。

然而,我强烈建议您这样做的方法是使用rename-in在导入时重命名这些功能。例如,您的代码如下所示:

#lang racket

(require (rename-in racket/sequence
                    [sequence-length s-length]
                    [sequence-map s-map]
                    [sequence-filter s-filter]
                    ...))

还有其他更高级的方法,您无需使用module->exportsregexp-matchformat-idmake-require-transformer明确列出每个标识符。但这对我来说似乎很脆弱,你最好明确指出你要重命名的名字。