2016-08-20 8 views
1

Kann ich ein Makro erstellen, so dass ich sequence- Funktionen mit einer s- aufrufen kann? Daher sollte ich s-length, s-filter und s-map anstelle von sequence-length, sequence-filter und sequence-map schreiben können. Vielen Dank.Makro zum Umbenennen von Sequenz- Funktionen

Antwort

3

Sie können filtered-in von racket/require verwenden, um diese Art von Transformation durchzuführen. Hier ist ein einfaches Beispiel:

#lang racket 

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

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

Wenn Sie sich mit dieser Art der Sache oft finden, wäre es nicht zu hart sein, um ein require transformer zu schreiben, den filtered-in erweitern würde:

#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 ...)))]))) 

dann können Sie es wie folgt verwenden:

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

Sollte dies irgendwo in einer Bibliothek gestellt werden? –

+0

@AlexKnauth Möglicherweise. Es mag sinnvoll sein, es in "Racket/require" zu haben, aber ich habe es widerstrebend getan, neue Dinge zu "base" hinzuzufügen, da es das einzige Paket ist, das (offensichtlich) nicht in älteren Racket-Versionen verwendet werden kann. Ich bin mir nicht sicher, ob wir es in einem separaten Paket haben würden, aber das macht Sinn, aber mit einigen anderen Transformatoren, die ich geschrieben habe, könnte es sich lohnen. –

1

Ja, es gibt. Um die Ebenen der Cludgyness zu verstehen.

Die Art, wie ich empfehle Sie jedoch, ist zu verwenden rename-in Um jede dieser Funktionen beim Import umzubenennen. So würde zum Beispiel der Code wie folgt aussehen:

#lang racket 

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

Es gibt noch weitere fortgeschrittenere Möglichkeiten, dies zu tun, die Sie nicht explizit erforderlich, um jede Kennung auflisten, mit module->exports, regexp-match, format-id und make-require-transformer. Aber das scheint mir spröde zu sein, und es ist besser, wenn Sie explizit angeben, welche Namen Sie umbenennen wollen.

Verwandte Themen