传递一个函数来计算方案中列表中的出现次数

passing a function to count occurences in a list in scheme

我正在尝试制作一个辅助函数来传递一个函数,例如 even?还是奇怪?并计算列表中出现的次数。我似乎开发了完美的逻辑,但出现错误(在底部),但无法弄清楚原因。我将 '(cdr L) 作为字符串传递,并将它的汽车作为整数使用,为什么它会说给定 'cdr? L is supposed to be a list and '(cdr L) 应该是一个列表.. 为什么这不是工作?

(define (fhelper F L )
    (if (> (length L) 1)
    (if (F (car L)) (+ 1 (fhelper F '(cdr L)))
                    (+ 0 (fhelper F '(cdr L))) )

    (if(F (car L))  1
                    0
                    )
                    )
    )

(fhelper even? '(1 2 3 4 ))
. . even?: contract violation
  expected: integer
  given: 'cdr

我尝试测试以查看 (even? (car '(1 2)) returns #f 所以我知道我的 (F (car L)) 部分没有问题,所以它几乎似乎递归调用正在将 F 应用于 '(cdr L) 而不是将它们用作参数,我没有得到,因为我仔细检查了文档并且看起来应该可以工作??

正如我在评论中所写,您不能引用 (cdr L) 因为您希望执行调用。

您似乎对自己的代码很满意,但它不是很地道;它应该看起来像

(define (fhelper func lst)
  (if (null? lst)
      0
      (+ (if (func (car lst)) 1 0)
         (fhelper func (cdr lst)))))

或者,作为尾递归过程:

(define (fhelper func lst)
  (let loop ((lst lst) (count 0))
    (if (null? lst)
        count
        (loop (cdr lst)
              (if (func (car lst)) (add1 count) count)))))

如果您熟悉 foldl 的另一种解决方案:

(define (fhelper f l)
  (foldl (λ (x xs) (if (f x) (add1 xs) xs))
         0
         l))