【问题标题】:Mutable versions of cadr, caddr, etccadr、caddr等的可变版本
【发布时间】:2011-09-08 13:29:36
【问题描述】:

我想知道如何在不单独定义每个版本的情况下在 Racket 中实现可变版本的 cadr、caddr 等? IE。不是

(define (mcadr exp)
    (mcar (mcdr exp)))

似乎对于可变列表或对,Racket 仅支持 mcar 和 mcdr,但不支持“扩展”版本。我是否需要了解并擅长宏才能做到这一点?

【问题讨论】:

    标签: macros scheme racket


    【解决方案1】:

    你可以这样做:

    (define mcaar (compose mcar mcar))
    (define mcadr (compose mcar mcdr))
    ;; ...
    (define mcddddr (compose mcdr mcdr mcdr mcdr))
    

    但是没有真正的绕过重复。即使在 Racket 源代码中(查看 racket/src/list.c),也存在重复,尽管使用 C 宏进行了一些美化。

    【讨论】:

    • 是的,这可能是不涉及宏的解决方案的最佳选择。
    【解决方案2】:

    这是一个宏解决方案:

    #lang racket/base
    
    (require racket/mpair (for-syntax racket/base))
    
    (define-syntax (define-combinations stx)
      (syntax-case stx ()
        [(_ n) (integer? (syntax-e #'n))
         (let ([n (syntax-e #'n)])
           (define options (list (cons "a" #'mcar) (cons "d" #'mcdr)))
           (define (add-options r)
             (apply append
                    (map (λ (opt)
                           (map (λ (l) (cons (string-append (car opt) (car l))
                                             (list (cdr opt) (cdr l))))
                                r))
                         options)))
           (define combinations
             (cdddr
              (let loop ([n n] [r '(("" . x))])
                (if (zero? n) r (append r (loop (sub1 n) (add-options r)))))))
           (define (make-name combo)
             (let ([s (string->symbol (string-append "mc" (car combo) "r"))])
               (datum->syntax stx s stx)))
           (with-syntax ([(body ...) (map cdr combinations)]
                         [(name ...) (map make-name combinations)])
             #'(begin (define (name x) body) ...)))]))
    
    (define-combinations 4)
    (mcaddr (mlist 1 2 3 4 5))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-08
      • 1970-01-01
      • 2016-04-09
      • 2015-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多