来自"Realm of Racket"的奇怪代码示例



我目前正在阅读《球拍之境》一书,到目前为止我真的很喜欢。但是,在第 4 1/2 章的第 74 页中,有一个我没有得到的代码示例。也许我的头脑拒绝弄清楚,因为我正在度假,但是,我根本不明白它的作用。

(define (winners lst pred)
  (cond
    [(empty? lst) (list pred)]
    [else
      (define fst (first lst))
      (if (score> (record-score pred) (record-score fst))
        (list pred)
        (cons pred (winners (rest lst) fst)))]))

他们在书中并没有真正解释它。不过,他们给出了一些提示:

  • "该功能的目的是从游戏记录列表中挑选第一名的完成者。
  • "我们有以下形状的结构定义:(结构记录(名称分数((">
  • ">LST是此类记录的列表,而PRED就是这样一种记录。的确,原始列表是(缺点 pred lst(,它是根据分数排序的。
  • "你明白,赢家是一个吃清单的功能,一次要经历一个记录。当至少有一个其他记录时,它会选择第一个,将其命名为 fst,并比较 fst 及其前置记录的分数。根据结果,所有获胜记录都被选中,或者获胜者必须继续寻找得分相等的球员。

我想score>是一个错字。除此之外,我完全理解代码 - 在语法和语义方面。我只是没有得到它的实际用途。这是什么,为什么有人想要那个?

不幸的是,您显示的代码只是为了向您展示本地定义的工作原理。在同一示例中,您还会看到根本不起作用(define sorted-lst (sort lst ...))

下面是第 75 页的完整示例代码,其中包含第 74 页的所有部分:

(define (winning-players lst)
  (define sorted-lst (sort lst ...)) ;; local variable 
  (define (winners lst pred)         ;; locally defined procedure
    (cond
      [(empty? lst) (list pred)]
      [else
       (define fst (first lst))
       (if (score> (record-score pred) (record-score fst))           
           (list pred)           
           (cons pred (winners (rest lst) fst)))]))
  ;; START HERE:
  ;; uses both local variable and the locally defined procedure
  (winners (rest sorted-lst) (first sorted-lst))) 

他们试图在下面的代码中展示的是,在winning-players之外,您无法访问sorted-list或使用过程winners因为它隐藏在winning-players范围内。

例如,如果您尝试在球拍交互窗口中使用(winners ...),您将获得:

获胜者:未定义; 无法引用未定义的标识符

如果你明白你可以继续在第5章:)

与球拍捆绑在一起,您拥有书中代码中的所有代码 racket/collects/realm .有 2 个过程定义称为 winners 。第一个在chapter 10,第二个在chapter 12.

至于代码的作用的答案。代码中有错误,因此我们需要修复它。我的猜测是这个分数>比较了两个记录的分数。我猜应该是这样的:

(struct record (name score) #:transparent)
(define (winning-players lst)
  (define (score> e1 e2)  ; defines a new local procedure
    (> (record-score e1)  ; that compares two records 
       (record-score e2)))
  ;; define sorted-list to be lst sorted by score in decreasing order
  (define sorted-lst (sort lst score>))  
  ;; procedure winners reduces the list to the elements 
  ;; that have same score as pred
  (define (winners lst pred)            
    (cond
      [(empty? lst) (list pred)]
      [else
       (define fst (first lst))
       (if (score> pred fst)           ;; changed to work with records
           (list pred)           
           (cons pred (winners (rest lst) fst)))]))
  ;; START HERE:
  ;; uses both local variable and the locally defined procedure
  (winners (rest sorted-lst) (first sorted-lst))) 
(define scores (list (record "John" 10) 
                     (record "Ben" 5) 
                     (record "Mary" 10) 
                     (record "Owen" 2)))  
(winning-players scores) 
; ==> (list (record "John" 10) (record "Mary" 10))

它返回所有得分最高的列表。

(winners (cdr lst) (car lst))

lst中产生不递减的记录。 pred代表"前任"(在列表中(。我认为score>是一个比较数十条记录的过程(即 record-score似乎产生了记录的分数,score>比较了这些分数(。

给定列表lst其前缀的 IOW 生成,以便其中记录条目的分数按非递减顺序排列。

说明指出在应用winners之前对列表进行排序。这只有在按记录分数的降序排序时才有意义。比递减列表的非递减前缀实际上将包含所有具有相等分数的记录 - 最大值。"赢家"。

清单按不递增顺序排序的前提条件应该在那里更清楚、更突出地说明。

最新更新