创建球拍错误消息

Creating a Racket error message

我很难为递归函数创建一条简单的错误消息。我有这个程序:

(check-expect (rewrite '(x x x - x x x x) 3 'x)
       (list 'x 'x 'x 'x 'x 'x 'x 'x))
(check-error (rewrite '(5 4 3 2 1) 5 6) 
         "rewrite: 5 is too large for (5 4 3 2 1)")

(define (rewrite init-ls init-n init-val)
  (local [(define (help ls n val)
            (cond 
              [(zero? n) (cons val (rest ls))]
              [(empty? ls) (error 'rewrite 
                                       (format "~s is too large for ~s"
                                                init-n init-ls))]      
              [else (cons (first ls) 
                          (rewrite (rest ls) (sub1 n) val))]))]
        (help init-ls init-n init-val) ))

基本上它只是将列表中位置 n 的元素替换为您选择的 val(值)。当 n 大于列表的长度时,我根本无法得到错误消息。

*我不想使用(长度列表),因为当您开始将大量项目放入列表时,这显然会非常慢

我试过不使用本地函数,将它放在(零?)之上,并以多种方式放在本地函数之外,但就是无法让它工作。 ISL+

中的任何帮助都会很棒

这里有两个小问题。首先是检查 zero?empty? 的子句应该颠倒过来,因为 zero? 的情况假定一个非空列表。

更重要的问题可能只是一个错字。当你重复出现时,你调用 rewrite 本身,而不是 help:

[else (cons (first ls) 
            (rewrite (rest ls) (sub1 n) val))]

您应该改为调用 help,这将保留 init-lsinit-n 的值以用于您的错误消息。

固定代码如下所示:

(define (rewrite init-ls init-n init-val)
  (local [(define (help ls n val)
            (cond
              [(empty? ls) (error 'rewrite
                                  (format "~s is too large for ~s"
                                          init-n init-ls))]
              [(zero? n) (cons val (rest ls))]
              [else (cons (first ls)
                          (help (rest ls) (sub1 n) val))]))]
    (help init-ls init-n init-val)))