如何修复 'cannot change constant' 错误
How to fix the 'cannot change constant' error
到目前为止我有这个代码
(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
我不确定如何解决这个问题或它意味着什么。
如果你把它放在定义 window 中(上面那个)一切正常。
#lang racket
(define (max f g)
(define (int-max x y)
(if (> x y) x y))
(lambda (x) (int-max (f x) (g x))))
您面临的问题是 max
已经定义,您正在尝试 re-define 它。
更重要的是,名称 max
不适合您尝试使用它的目的。您正在使用几个函数参数调用 max
。它returns一个可以用变量调用的lambda
。
您设想的用法如
((max sin cos) 10)
max-proc-value
这样的名称会更合适,并且会避免 运行 遇到的问题。
在左下角的 DrRacket 中有一个下拉菜单,您可以在其中 select 语言。从那里您可以 select "Choose language" 并单击 "Show details"。对于 R5RS 等遗留语言,您可以选择 "Disallow redefinition of initial bindings"。
现在根据 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))))
当然,这也适用于 #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))))
到目前为止我有这个代码
(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
我不确定如何解决这个问题或它意味着什么。
如果你把它放在定义 window 中(上面那个)一切正常。
#lang racket
(define (max f g)
(define (int-max x y)
(if (> x y) x y))
(lambda (x) (int-max (f x) (g x))))
您面临的问题是 max
已经定义,您正在尝试 re-define 它。
更重要的是,名称 max
不适合您尝试使用它的目的。您正在使用几个函数参数调用 max
。它returns一个可以用变量调用的lambda
。
您设想的用法如
((max sin cos) 10)
max-proc-value
这样的名称会更合适,并且会避免 运行 遇到的问题。
在左下角的 DrRacket 中有一个下拉菜单,您可以在其中 select 语言。从那里您可以 select "Choose language" 并单击 "Show details"。对于 R5RS 等遗留语言,您可以选择 "Disallow redefinition of initial bindings"。
现在根据 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))))
当然,这也适用于 #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))))