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

use*_*321 2 scheme overloading module 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)))
Run Code Online (Sandbox Code Playgroud)

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

谢谢.

Gre*_*ott 5

我如何做到这一点是使用except-inrename-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)
Run Code Online (Sandbox Code Playgroud)

你也可以使用prefix-inonly-in,这将是,如果你有很多这样的功能来命名更方便:

(require (except-in racket + -)
         (prefix-in old (only-in racket + -)))
Run Code Online (Sandbox Code Playgroud)

几点:

  • quatplus只是返回一个新的不可变向量(而不是使用make-vectorset!).它更简单,也可能更快.

  • Racket +接受任意数量的参数.也许你应该?

  • 如上所述,你的新作+将失败,因为non vector和a 的结合vector.你可能想解决这个问题:

    (+ 1 (vector 1 2 3 4))
    ; +: contract violation
    ;   expected: number?
    ;   given: '#(1 2 3 4)
    ;   argument position: 1st
    ;   other arguments...:
    ;    1
    
    Run Code Online (Sandbox Code Playgroud)