【问题标题】:How to fix contract violation errors in scheme DrRacket?如何修复方案 DrRacket 中的合同违规错误?
【发布时间】:2020-06-16 20:52:35
【问题描述】:
(define is1?
  (lambda (tuple)
    (if (and (= 2 (length tuple))
             (= 1 (- (cadr tuple) (car tuple)))
             (list? tuple))
        #t
        #f)))

(define greenlist?
  (lambda (x) (andmap is1? x)))

(greenlist? '((2 4 6) (5 6) (1 2)))
(greenlist? '(3 4 5 6))

第二个命令:(greenlist? '(3 4 5 6)) 在应该返回 false 时返回错误。 相反,我得到了这个错误:

长度:违反合同
预期:列表?
给定:3

我应该在我的代码中进行哪些更改以使其返回 false 而不是错误?

这是绿名单的定义:

绿色列表是整数对的非空列表,其中一对 integers 是正好两个整数的列表,其中每一对 '( x y) 具有 y – x = 1 的属性。

例如:'((5 6) (3 4) (2 3) (-5 -4)) 是绿名单。

【问题讨论】:

  • 请使用能够正确缩进代码的编辑器,您不应该只使用右括号编写行。看我的回答,这是在 Scheme 中格式化代码的正确方法。
  • 感谢您告诉我。

标签: list scheme racket


【解决方案1】:

问题在于条件的顺序很重要:在and 表达式中,条件按从左到右的顺序计算,如果一个条件是false,那么其他条件被跳过(短路评估)。

您的输入是一个列表列表,因此您应该首先测试当前元素是否是一个实际列表 - 否则您将尝试获取不是的对象的length一个列表(在您的示例中为数字 3),这是一个错误。

顺便说一句:可以简化代码,你实际上不需要使用if,只需返回条件的值即可:

(define is1?
  (lambda (tuple)
    (and (list? tuple) ; you must ask this first!
         (= 2 (length tuple))
         (= 1 (- (cadr tuple) (car tuple))))))

【讨论】:

  • 谢谢,它有效。当我运行 (greenlist? "green apples" ) 时,当我应该得到错误时,我得到了同样的错误。如何让它返回 false 而不是出错?
  • 那你还需要检查输入是否是一个列表,在绿名单中?功能。但老实说,您不应该检查类型是否正确,如果用户传递了错误的类型,那不是您的问题,这是一种动态类型的语言,您不必担心检查这些错误。例如,如果输入是 ‘((”x” “y”)) 怎么办?这将是另一个需要检查的情况。
  • 可以使用define/contract 断言tuple(listof int?)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-10
  • 1970-01-01
  • 2016-03-19
相关资源
最近更新 更多