【问题标题】:Argument overwrite doesn't work in scheme/racket参数覆盖在方案/球拍中不起作用
【发布时间】:2015-08-24 20:51:20
【问题描述】:

我对 Racket/Scheme 非常陌生。我知道基本语法。
我写了一个程序,用 list2 做 list1 的笛卡尔积。我使用 Dr Racket 调试了程序。似乎当 l2 变为 null 时,程序不会将 l2 替换为原始列表,即 ol2(这是我想要做的)。
我无法弄清楚为什么会这样。

 (define product   (lambda (ol2 l1 l2)  
     (cond  
       [(and (null? l1) (null? l2)) '()]  
       [(null? l2) (product ol2 (rest l1) ol2)]  
       [else (cons (list (first l1) (first l2)) (product ol2 l1 (rest l2)))])))  

【问题讨论】:

  • headfirst(或car)的别名吗?
  • @AlexisKing 是的,它是 head 的别名。为了清楚起见,我已经编辑了代码。
  • 尝试使用(require racket/trace)(trace-define (product ol2 l1 l2) ...),然后在REPL中运行该函数。这可能有助于使问题更加清晰。
  • ol2 是干什么用的?
  • l1empty? 时,基本情况应该停止,因为当l1 变为empty? l2 被重置为ol2

标签: recursion scheme racket


【解决方案1】:

在您的原始代码中:

(define product   (lambda (ol2 l1 l2)  
     (cond  
       [(and (null? l1) (null? l2)) '()]  
       [(null? l2) (product ol2 (rest l1) ol2)]  ; here l1 gets empty and l2 becomes the same as ol2
       [else (cons (list (first l1) (first l2)) (product ol2 l1 (rest l2)))])))  

基本情况要求l1l2 都为null?,但由于l2ol 替换,同时l1 从一个元素变为零,两者都不会null 因为l2 将是原始列表。

那么默认情况下会尝试在空列表上使用first。要解决此问题,只需将基本情况更改为在 l1null? 时终止:

(define product   (lambda (ol2 l1 l2)  
     (cond  
       [(null? l1) '()] ; terminate when l1 is null? 
       [(null? l2) (product ol2 (rest l1) ol2)] 
       [else (cons (list (first l1) (first l2)) (product ol2 l1 (rest l2)))])))  

对于我或其他评论者来说,使用应该相同的额外变量并不明显。使用命名的let 或本地帮助程序隐藏了用户不必关心的实现细节:

;; with named let
(define (product l1 l2)
  (let product ((l1 l1) (tl2 l2)) 
    (cond  
      [(null? l1) '()] ; terminate when l1 is null? 
      [(null? tl2) (product (rest l1) l2)] 
      [else (cons (list (first l1) (first tl2)) (product l1 (rest tl2)))])))  

;; with local helper procedure
(define (product l1 l2)
  (define (product l1 tl2) 
    (cond  
      [(null? l1) '()] ; terminate when l1 is null? 
      [(null? tl2) (product (rest l1) l2)] 
      [else (cons (list (first l1) (first tl2)) (product l1 (rest tl2)))]))
  ;; call the helper
  (product l1 l2))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-20
    • 2016-11-16
    相关资源
    最近更新 更多