球拍/方案中的运算符重载

时间:2014-02-14 00:14:12

标签: module scheme overloading racket

我在这里遇到了一些麻烦,希望你们能帮忙。

基本上,我想要做的是重载球拍中的+号,这样它就会添加两个向量而不是两个数字。另外,我想保留旧的+运算符,以便我们仍然可以使用它。我知道这应该在计划中工作,所以我被告知我需要使用模块*在球拍中进行。我仍然不完全确定这一切是如何运作的。

这是我到目前为止所做的:

#lang racket

(module* fun scheme/base 
  (define old+ +) 
  (define + new+)

  (define (new+ x y)
    (cond ((and (vector? x) (vector? y))
           (quatplus x y))
          (else (old+ x y))))

  (define (quatplus x y)
    (let ((z (make-vector 4)))
      (vector-set! z 0 (old+ (vector-ref x 0) (vector-ref y 0)))
      (vector-set! z 1 (old+ (vector-ref x 1) (vector-ref y 1)))
      (vector-set! z 2 (old+ (vector-ref x 2) (vector-ref y 2)))
      (vector-set! z 3 (old+ (vector-ref x 3) (vector-ref y 3)))
      z)))

但它似乎根本没有做任何事情。如果有人对此有所了解,我将非常感激。

谢谢。

2 个答案:

答案 0 :(得分:5)

我如何才能使用except-in的{​​{1}}和rename-in规范:

require

您还可以将#lang racket/base (require (except-in racket + -) (rename-in racket [+ old+] [- old-])) (define (+ x y) (cond [(and (vector? x) (vector? y)) (quatplus x y)] [else (old+ x y)])) (define (quatplus x y) (vector (+ (vector-ref x 0) (vector-ref y 0)) (+ (vector-ref x 1) (vector-ref y 1)) (+ (vector-ref x 2) (vector-ref y 2)) (+ (vector-ref x 3) (vector-ref y 3)))) (+ (vector 1 2 3 4) (vector 1 2 3 4)) ;; => #(2 4 6 8) prefix-in一起使用,如果您有许多此类功能需要重命名,这会更方便:

only-in

几点:

  • 我让(require (except-in racket + -) (prefix-in old (only-in racket + -))) 只返回一个新的不可变向量(而不是使用quatplusmake-vector)。它更简单,也可能更快。

  • 球拍的set!接受任意数量的参数。也许你应该?

  • 如上所述,您的新+将因非+vector的组合而失败。你可能想解决这个问题:

    vector

答案 1 :(得分:2)

您可以使用Scheme封装来满足您的需求:

(import (rename (rnrs) (+ numeric+)))

(define +
  (let ((vector+ (lambda (v1 v2) (vector-map numeric+ v1 v2)))
        (list+   (lambda (l1 l2) (map        numeric+ l1 l2)))
        ;; … 
        )
   (lambda (a b)
     (cond ((and (vector? a) (vector? b)) (vector+ a b))
           ((and (list?   a) (list?   b)) (list+   a b))
           ;; …
           (else (numeric+ a b))))))

如果你想加入任何深度,这应该有效:

(define +
  (letrec ((vector+ (lambda (v1 v2) (vector-map any+ v1 v2)))
           (list+   (lambda (l1 l2) (map        any+ l1 l2)))
           (any+    (lambda (a b)
                      (cond ((and (vector? a) (vector? b)) (vector+ a b))
                            ((and (list?   a) (list?   b)) (list+   a b))
                            ;; …
                            (else (numeric+ a b))))))
     any+))

请参阅:

> (+ (vector (list 1 2) 3) (vector (list 11 12) 13))
#((12 14) 16)