Module 球拍/方案中的操作员超载
我在这里遇到了一些麻烦,希望你们能帮忙 基本上,我要做的是在球拍中重载+符号,这样它将添加两个向量,而不是两个数字。另外,我想保留旧的+运算符,以便我们仍然可以使用它。我知道这应该在scheme中起作用,所以有人告诉我需要使用模块*在racket中完成。我仍然不能完全确定这一切是如何运作的 以下是我到目前为止的情况:Module 球拍/方案中的操作员超载,module,scheme,overloading,racket,Module,Scheme,Overloading,Racket,我在这里遇到了一些麻烦,希望你们能帮忙 基本上,我要做的是在球拍中重载+符号,这样它将添加两个向量,而不是两个数字。另外,我想保留旧的+运算符,以便我们仍然可以使用它。我知道这应该在scheme中起作用,所以有人告诉我需要使用模块*在racket中完成。我仍然不能完全确定这一切是如何运作的 以下是我到目前为止的情况: #lang racket (module* fun scheme/base (define old+ +) (define + new+) (define (n
#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)))
但它似乎什么也没做。如果有人知道这件事,我将非常感激
谢谢。我将如何做到这一点是使用
中的和中的重命名规范,以满足要求
:
#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)
您还可以将
中的前缀与
中的一起使用,如果您有许多这样的函数可以重命名,这将更加方便:
(require (except-in racket + -)
(prefix-in old (only-in racket + -)))
有几点:
- 我让
quatplus
只返回一个新的不可变向量(而不是使用makevector
和set!
)。它更简单,而且可能更快
- Racket的
+
接受任意数量的参数。也许你的应该
- 如前所述,如果组合使用非
向量
和向量
,则新的+
将失败。您可能想解决这个问题:
(+ 1 (vector 1 2 3 4))
; +: contract violation
; expected: number?
; given: '#(1 2 3 4)
; argument position: 1st
; other arguments...:
; 1
您可以使用方案封装来满足以下需求:
(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+))
见:
作为警告,不要诋毁你的问题。如果你再这样做,我将锁定问题,并可能暂停你的帐户。什么是诽谤问题?诽谤意味着大幅编辑帖子以改变其含义。在本例中()OP试图混淆整个帖子。
> (+ (vector (list 1 2) 3) (vector (list 11 12) 13))
#((12 14) 16)