Схема (DrRacket) - вызов обобщенной / абстрагированной функции с другой функцией
Для справки я программирую на Scheme с использованием DrRacket.
Для этой проблемы я делаю обобщенную / абстрактную функцию (в которой не используются функции более высокого порядка и / или лямбду), называемую tally-by
функции 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
определения функций, так как я не уверен, что делать.
2 ответа
В точках подсчета вы звоните (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
который использует tally-by
бы просто позвонить tally
с аргументом он получил с правильным helper
:
(define (tally-by-place-points aloc alov)
(tally-by total-points-for aloc alov))
Кстати, ваше упоминание о том, какой язык вы используете, неоднозначно. Из синтаксиса вы, скорее всего, программируете ракетку в DrRacket. Я думаю, вы первая строка #lang scheme
(#!scheme
для краткости) или #!racket
, которые являются синонимами, а не официальным языком Схемы. Для реального языка Схемы вам нужно использовать #!r6rs
или же #!r5rs
и программа в соответствии с теми.
Абстракция - это чисто синтаксическая трансформация! Это просто бета-сокращение в обратном порядке:
..... 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
Параметр теперь, с любым именем, которое мы хотим (если имя уникально).