作为参考,我使用DrRacket进行Scheme编程。
对于这个问题,我正在使用函数tally-by
的通用/抽象函数(不使用高阶函数和/或lambda) tally-by-place-points
定义如下:
(define listofCandidates
(list "Blake" "Ash" "Bob" "Will" "Joey"))
;; Signature: tally-by-place-points:
;; list-of-candidates list-of-votes -> list-of-Voting-Tallies
;; Purpose: Consumes a list of candidate names and a list of votes and
;; produces a list of voting-tallies.
;; (Points-Per-Place strategy).
;; Tests:
(check-expect (tally-by-place-points empty empty) empty)
(check-expect (tally-by-place-points listofCandidates listofVotes)
(cons (make-voting-tally "Blake" 7)
(cons (make-voting-tally "Ash" 3)
(cons (make-voting-tally "Bob" 5)
(cons (make-voting-tally "Will" 1)
(cons (make-voting-tally "Joey" 2) empty))))))
;; Define:
(define (tally-by-place-points aloc alov)
(cond
[(empty? aloc) empty]
[else (cons (make-voting-tally (first aloc)
(total-points-for (first aloc) alov))
(tally-by-place-points (rest aloc) alov))]))
这就是我提出的(不确定它是否正确):
;; Signature: tally-by: (helper function)
;; list-of-candidates list-of-votes -> list-of-Voting-Tallies
;; Purpose: Consumes a helper function, a list of candidate names,
;; and a list of votes and produces a list of voting-tallies.
;; Define:
(define (tally-by helper aloc alov)
(cond
[(empty? aloc) empty]
[else (cons (make-voting-tally (first aloc)
(tally-by helper (first aloc) alov))
(tally-by helper (rest aloc) alov))]))
我应该注意,这是我所指的帮助函数,total-points-for
:
;; Signature: total-points-for: string list-of-strings -> number
;; Purpose: Consumes a name and a list of votes and produces the
;; number of points that the given name has received
;; using a points-per-place strategy.
;; Tests:
(check-expect (total-points-for "Ash" empty) 0)
(check-expect (total-points-for "Ash" listofVotes) 3)
(check-expect (total-points-for "Blake" listofVotes) 7)
(check-expect (total-points-for "Bob" listofVotes) 5)
(check-expect (total-points-for "Will" listofVotes) 1)
(check-expect (total-points-for "Joey" listofVotes) 2)
(check-expect (total-points-for "Brad" listofVotes) 0)
;; Define:
(define (total-points-for cand alov)
(cond
[(empty? alov) 0]
[(string=? (vote-choice1 (first alov)) cand)
(+ 3 (total-points-for cand (rest alov)))]
[(string=? (vote-choice2 (first alov)) cand)
(+ 2 (total-points-for cand (rest alov)))]
[(string=? (vote-choice3 (first alov)) cand)
(+ 1 (total-points-for cand (rest alov)))]
[else (total-points-for cand (rest alov))]))
我现在必须修改tally-by-place-points
函数来调用我刚刚创建的广义/抽象函数tally-by
。我应该注意签名,目的和检查期望都是正确的。这是我提出的功能,虽然定义不正确:
;; Signature: tally-by-place-points:
;; list-of-candidates list-of-votes -> list-of-Voting-Tallies
;; Purpose: Consumes a list of candidate names and a list of votes
;; and produces a list of voting-tallies.
;; (Points-Per-Place strategy).
;; Tests:
(check-expect (tally-by-place-points empty empty) empty)
(check-expect (tally-by-place-points listofCandidates listofVotes)
(cons (make-voting-tally "Blake" 7)
(cons (make-voting-tally "Ash" 3)
(cons (make-voting-tally "Bob" 5)
(cons (make-voting-tally "Will" 1)
(cons (make-voting-tally "Joey" 2) empty))))))
;; Define:
(define (tally-by-place-points aloc alov)
(cond
[(empty? aloc) empty]
[else (cons (make-voting-tally (first aloc)
(tally-by (first aloc) alov))
(tally-by (rest aloc) alov))]))
我希望有人能够帮助我处理我的tally-by
和修改后的tally-by-place-points
函数定义,因为我不确定该怎么做。
答案 0 :(得分:2)
抽象是纯粹的语法转换!它反过来只是 beta-reduction :
..... a ..... ==> (λa. ..... a ..... ) a
也就是说,您只需将一些实体用于函数的参数,并将该实体作为函数调用中的参数传递。这样,之前具体的内容现在被概括,变成一个参数,抽象结束:
(define (tally-by-place-points aloc alov)
(cond ; ~~~~~~~~~~~~
[(empty? aloc) empty]
[else (cons (make-voting-tally (first aloc)
(total-points-for (first aloc) alov))
; ^^^^^^^^^^^^^^^^^
(tally-by-place-points (rest aloc) alov))]))
重写为
(define (tally-by place-points aloc alov)
(cond ; ~~~~~~~~~~~~
[(empty? aloc) empty]
[else (cons (make-voting-tally (first aloc)
(place-points (first aloc) alov))
; ^^^^^^^^^^^^^^^^
(tally-by-place-points (rest aloc) alov))]))
以便通话
(tally-by total-points-for aloc alov)
相当于之前的电话
(tally-by-place-points aloc alov)
这当然需要在递归调用中进行整理 - 它也需要进行转换:
(define (tally-by place-points aloc alov)
(cond ; ~~~~~~~~~~~~
[(empty? aloc) empty]
[else (cons (make-voting-tally (first aloc)
(place-points (first aloc) alov))
(tally-by place-points (rest aloc) alov))]))
; ~~~~~~~~~~~~
因为我们将(tally-by-place-points ...
替换为(tally-by place-points ...
- 无处不在。
当然,我们现在可以使用我们想要的任何名称重命名place-points
参数(只要名称是唯一的)。
答案 1 :(得分:1)
在逐个积分中,您可以拨打(total-points-for (first aloc) alov)
来获取地点积分。在tally-by
中,如果您将total-points-for
作为参数helper
传递,则应该能够完全相同。因此,您需要将total-points-for
的引用替换为helper
,并在递归时传递帮助:
(define (tally-by helper aloc alov)
(cond
[(empty? aloc) empty]
[else (cons (make-voting-tally (first aloc)
(helper (first aloc) alov))
(tally-by helper (rest aloc) alov))]))
在使用tally-by-place-points
的{{1}} tally-by
中,只需使用正确的tally
获得的参数调用helper
:
(define (tally-by-place-points aloc alov)
(tally-by total-points-for aloc alov))
顺便说一句,你提到你使用的语言是模棱两可的。从语法中你最有可能在DrRacket中编程。我猜你的第一行是#lang scheme
(简称#!scheme
)或#!racket
,它们是同义词,而不是官方的Scheme语言。对于实际的Scheme语言,您需要使用#!r6rs
或#!r5rs
并根据这些语言进行编程。