2

我有这个程序:

(define count-calls
  (let ((count 0))
    (lambda char  
           (cond ((null? char) 
                  (begin(set! count (+ 1 count))
                        count))
                 ((eq? char 'how-many-calls) count)
                 ((eq? char 'reset) (set! count 0))))))

当调用 (count-calls) 时,它确实加 1,但是当我调用 (count-calls 'how-many-calls) 时,它不能按预期工作。我发现如果你定义 (lambda (char) 而不是 (lambda char) 则找到 (eq? ...) 部分,但对于 (lambda char) 它似乎无法识别 char。

4

3 回答 3

3

You have a couple of coding errors, this should fix them:

(define count-calls
  (let ((count 0))
    (lambda char
      (cond ((null? char) 
             (set! count (+ 1 count))
             count)
            ((eq? (car char) 'how-many-calls)
             count)
            ((eq? (car char) 'reset)
             (set! count 0))))))

In particular, notice that:

  • If a lambda's parameters are not surrounded by parenthesis (as is the case with char), then the procedure expects a list of arguments with variable size, possibly empty
  • With that in mind, it's clear why you need to do (car char) for extracting a parameter, if it was provided
  • It's not necessary to use a begin after a condition in cond, it's implicit

Use the procedure like this:

(count-calls)
=> 1
(count-calls 'how-many-calls)
=> 1
(count-calls 'reset)
=> 
(count-calls 'how-many-calls)
=> 0
于 2013-02-21T18:58:36.163 回答
3

如果您在 lambda 参数周围没有括号,那么您将获得列表中的所有参数。因此,您的代码正在将“多少调用”与列表进行比较。

Welcome to DrRacket, version 5.3.3.5 [3m].
Language: racket [custom]; memory limit: 8192 MB.
> ((lambda args (displayln args)) "a")
(a)
> ((lambda args (displayln args)) "a" "b")
(a b)
> ((lambda (args) (displayln args)) "a")
a
> ((lambda (args) (displayln args)) "a" "b")
#<procedure>: arity mismatch;
 the expected number of arguments does not match the given number
  expected: 1
  given: 2
  arguments...:
   "a"
   "b"
于 2013-02-21T18:49:56.557 回答
1

扩展stchang的答案,这是解决此问题的一种方法:

(define count-calls
  (let ((count 0))
    (case-lambda
      (() (set! count (+ 1 count)) count)
      ((char) (cond
                ((eq? char 'how-many-calls) count)
                ((eq? char 'reset ) (set! count 0) 'reset)
                (else 'wot?))))))
于 2013-02-21T19:02:56.853 回答