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

时间:2015-11-09 06:53:27

标签: functional-programming scheme racket

我正在尝试创建一个传递函数的辅助函数,例如偶数?还是奇怪的?并计算列表中出现的次数。我似乎开发了完美的逻辑,但我得到一个错误(在底部),但无法弄清楚为什么。我传递'(cdr L)作为一个字符串,并把它的汽车用作一个整数,为什么它会说给'cdr? L应该是一个列表,'(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

我试过测试看到(甚至?(car'(1 2))返回#f所以我知道它不是我的(F(车辆L))部分的问题,所以它几乎好像是递归调用正在将F应用于'(cdr L)而不是将它们用作参数,我没有得到这些参数,因为我检查了文档并且它看起来应该有用吗?

2 个答案:

答案 0 :(得分:2)

正如我在评论中写的那样,你不能引用(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)))))

答案 1 :(得分:2)

如果您熟悉它,请使用foldl的另一种解决方案:

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