如何修复'不能改变常数'错误

时间:2018-02-24 21:09:01

标签: scheme racket variable-assignment redefinition

到目前为止我有这个代码

(define (max f g) 
  (define (int-max x y)
    (if (> x y) x y))
  (lambda (x) (int-max (f x) (g x))))

它给了我错误define-values: assignment disallowed; cannot change constant constant: max

我不确定如何解决这个或它意味着什么。

3 个答案:

答案 0 :(得分:4)

在左下角的DrRacket中有一个下拉列表,您可以在其中选择lanaguage。从那里,您可以选择“选择语言”,然后单击“显示详细信息”。对于R5RS等传统语言,您可以选择“禁止重新定义初始绑定”。

现在根据R5RS,您的重新定义只能扩展功能,而原始绑定使用的数据类型应该在新定义中使用相同的功能。这样做的原因是能够不断折叠代码。因此,以下代码无效:

(define + -)
(+ 5 3)
; ==> 7

这可能看起来很奇怪,但该程序违反了报告,因此,就报告而言,结果可能也是字符串“banana”。在R5RS中,您需要使其与Scheme兼容:

(define numeric-max max)
(define max
  (lambda (v1 . vs)
    (if (number? v1)
        (apply numeric-max v1 vs)
        (lambda (x) (numeric-max (v1 x) ((car vs) x))))))

使用R6RS,您可以完全不导入绑定:

#!r6rs
(import (except (rnrs base) max))

(define (max f g) 
  (define (int-max x y)
    (if (> x y) x y))
  (lambda (x) (int-max (f x) (g x))))

如果您想使max可用,您可以使用命名导入在R5RS中执行相同操作:

#!r6rs
(import (except (rnrs base) max)
        (only (rnrs control) case-lambda)
        (rename (rnrs base) (max numeric-max)))

(define max
    (case-lambda
      ((v1 v2)
       (if (number? v1)
           (numeric-max v1 v2)
           (lambda (x) (numeric-max (v1 x) (v2 x)))))
      (args
       (apply numeric-max args))))

而且coruse也适用于#lang racket

#lang racket
(require (rename-in racket/base [max numeric-max]))      
(define max
    (case-lambda
      ((v1 v2)
       (if (number? v1)
           (numeric-max v1 v2)
           (lambda (x) (numeric-max (v1 x) (v2 x)))))
      (args
       (apply numeric-max args))))

答案 1 :(得分:2)

您遇到的问题是max已经定义,您正在尝试重新定义它。

更重要的是,名称max不适合您尝试使用它。您使用几个函数参数调用max。它返回一个lambda,可以使用变量调用。

您的构想用法,例如

((max sin cos) 10)

诸如max-proc-value之类的名称会更合适,并且可以避免您遇到的问题。

答案 2 :(得分:1)

如果你把它放在定义窗口(上面的那个)里,一切都会有效。

#lang racket
(define (max f g) 
    (define (int-max x y)
      (if (> x y) x y))
 (lambda (x) (int-max (f x) (g x))))