Scheme 方案R5RS合同违约
下面的代码是教授在我的“方案介绍”课程中对一个问题给出的答案,但它出现了一个错误。我不明白为什么Scheme 方案R5RS合同违约,scheme,r5rs,Scheme,R5rs,下面的代码是教授在我的“方案介绍”课程中对一个问题给出的答案,但它出现了一个错误。我不明白为什么 #!r5rs (define (make-complex a b) (cons a b)) (define (real x) (car x)) (define (imag x) (cdr x)) (define (complex-sqrt x) (define (sgn v) (cond ((< v 0) -1) ((= v 0) 0)
#!r5rs
(define (make-complex a b) (cons a b))
(define (real x) (car x))
(define (imag x) (cdr x))
(define (complex-sqrt x)
(define (sgn v)
(cond ((< v 0) -1)
((= v 0) 0)
(else 1)))
(let ((root (sqrt (+ (* (real x) (real x))
(* (imag x) (imag x))))))
(make-complex (sqrt (/ (+ (real x) root) 2))
(* (sgn (imag x))
(sqrt (/ (- root (real x)) 2))))))
(complex-sqrt 7)
;; ERROR mcar: contract violation
;; expected: mpair?
;; given: 7
#!r5rs
(定义(使复杂a b)(cons a b))
(定义(实x)(车x))
(定义(imag x)(cdr x))
(定义(复杂sqrt x)
(定义(sgn v)
(cond(
在DrRacket中运行时,我对trace Illustration的错误进行了分析 这是您转录的代码。请考虑在将来发布实际代码而不是截图。
(define (make-complex a b) (cons a b))
(define (real x) (car x))
(define (imag x) (cdr x))
(define (complex-sqrt x)
(define (sgn v)
(cond ((< v 0) -1)
((= v 0) 0)
(else 1)))
(let ((root (sqrt (+ (* (real x) (real x))
(* (imag x) (imag x))))))
(make-complex (sqrt (/ (+ (real x) root) 2))
(* (sgn (imag x))
(sqrt (/ (- root (real x)) 2))))))
这是正确的 复杂sqrt的实施是不安全的。这意味着它假设您传递一个复数,在本例中,是使用
make complex
创建的
要解决此问题,您需要检查参数是否复杂:
;; Not 100%. Should use `struct` to not
;; mix with random pairs that happens to have numeric parts
(define (complex? x)
(and (pair? x)
(number? (car x))
(number? (cdr x))))
;; The original code is renamed to unsafe-complex-sqrt
(define (complex-sqrt x)
(if (complex? x)
(unsafe-complex-sqrt x)
(raise-argument-error 'complex-sqrt "complex?" x)))
现在您可以测试它:
(complex-sqrt (make-complex 7 0))
; ==> (2.6457513110645907 . 0)
(complex-sqrt 7)
; ERROR complex-sqrt: contract violation
; expected: complex?
; given: 7
太好了。现在它表示您没有将所需的复数传递给需要复数才能工作的函数
那么原始代码中发生了什么?
在不安全复杂sqrt
中,它使用car
和cdr
这两种安全操作,如果(对x)
提供的参数x
不是#t
,则表示违反合同
球拍在其#中使用mcons
!r5rs
实现,因此错误指的是r5rs中以m为前缀的每个pair/list函数,因为错误不注意重命名
(complex-sqrt (make-complex 7 0))
; ==> (2.6457513110645907 . 0)
(complex-sqrt 7)
; ERROR complex-sqrt: contract violation
; expected: complex?
; given: 7