【问题标题】:How to fix the 'cannot change constant' error如何修复“无法更改常量”错误
【发布时间】:2018-02-24 21:09:00
【问题描述】:

到目前为止我有这个代码

(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

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

【问题讨论】:

标签: scheme racket variable-assignment redefinition


【解决方案1】:

在左下角的 DrRacket 中有一个下拉菜单,您可以在其中选择语言。从那里您可以选择“选择语言”并单击“显示详细信息”。对于 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))))

当然,这也适用于#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))))

【讨论】:

    【解决方案2】:

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

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

    您设想的用法,例如

    ((max sin cos) 10)
    

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

    【讨论】:

      【解决方案3】:

      如果你把它放在定义窗口(上面的那个)中,一切正常。

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

      【讨论】:

      • 你在 DrRacket 中选择了哪种语言?
      • 我是新手,所以我认为它只是基本的 R5RS
      • 啊! R5rs 是方案,而不是球拍。在 DrRacket 的左下角选择“Determine language from source”并添加#lang racket 作为你的第一行
      • 谢谢它可以用那个,但是它为什么不能用scheme
      • 好吧。如果我没记错的话,r5rs 标准并没有指定 repl 的工作方式。所以实施者决定不允许这样做。但是,您可以在语言菜单中更改行为。选择“选择语言”项,点击“显示详细信息”,然后取消勾选“强制常量定义”。
      猜你喜欢
      • 2018-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-24
      • 1970-01-01
      • 1970-01-01
      • 2019-12-29
      • 2021-10-24
      相关资源
      最近更新 更多