【问题标题】:first: contract violation error in racket/scheme for printing out a combination of list procedures第一:球拍/打印出列表程序组合的方案中的合同违规错误
【发布时间】:2021-01-07 23:07:59
【问题描述】:

我正在编写一个需要 2 个表达式的过程,如果有一种方法可以通过 exp2(当我们将 exp2 替换为 'sss)使用 first、rest、cons 创建 exp1,然后它会返回生成所需的代码exp1.

例如,这就是我想要制作的。

(find-in '(e r t) '(e t) ) => '(cons (first sss) (rest (rest sss)))

我的代码适用于很多测试用例,但是当我运行时

(find-in '(a '(((v)) l) (f g)) '( (v g) l a))

它返回此错误:

first: contract violation
  expected: (and/c list? (not/c empty?))
  given: 'g

当我尝试运行这个测试用例时出现同样的错误:

(find-in '(x a (x y)) '(z a (b))) 
;supposed to return #f

这是我目前的代码:

(define find-in
  (lambda (exp2 exp1)
    (cond
      ((equal? exp2 exp1) 'sss)
      ((null? exp2) #f)
      ((not (list? exp2)) #f)
      ((find-in (first exp2) exp1) (repl 'sss '(first sss) (find-in (first exp2) exp1)))
      ((find-in (rest exp2) exp1) (repl 'sss '(rest sss) (find-in (rest exp2) exp1)))
      (else (list? exp1)
            (if
             (and (find-in exp2 (first exp1)) (find-in exp2 (rest exp1)))
             (list 'cons (find-in exp2 (first exp1)) (find-in exp2 (rest exp1)))
             #f) #f))))

我对我在编码时错过了哪个条件或是否存在逻辑错误感到困惑。可能出了什么问题?

【问题讨论】:

  • 就像您最近提出的所有问题一样,这段代码确实可以受益于一些更具描述性的变量名称。 exp1 and exp2` 比 tofrom 更难跟踪 - 尤其是当你奇怪地选择在 exp1 之前写 exp2 时!

标签: list recursion error-handling scheme racket


【解决方案1】:

我觉得你的最后一个子句不合适。当您在最后一个子句中使用特殊的 else 标记时,您是在说“这里没有什么要测试的,如果您已经做到了这一点,就无条件地执行它的主体”。因此,就cond 而言,您的下一个表达式(list? exp1) 不是一个测试:它会评估副作用,并丢弃结果。然后还会计算下一个表达式,无论 exp1 是否是一个列表。

如果你想以exp1 是否是一个列表为条件,你应该在开头删除多余的else(并且可能在末尾添加一个else 子句以返回#f,如果没有您的案例匹配)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-28
    • 2016-08-30
    • 1970-01-01
    • 1970-01-01
    • 2020-09-07
    • 1970-01-01
    • 1970-01-01
    • 2020-10-11
    相关资源
    最近更新 更多