如何在Scheme中编写函数的函数

时间:2019-02-24 22:21:08

标签: scheme racket

我应该编写一个名为(nth-filtered f n)的函数,其中f是一个变量的函数,而n是一个自然数,其求和为第n个自然数,使得f应用于该号码的是#t

如果我们打电话给 (nth-filtered even? 1)我们将得到2

(nth-filtered prime? 10)我们将获得29

如何使它适用于任何顺序功能?解决此类问题时我应该考虑些什么?

2 个答案:

答案 0 :(得分:1)

变量是变量,+也是变量。函数和其他数据类型之间的主要区别在于,您可以在函数名称的括号内加上参数,它将成为一个新值。

例如

(define (double fun) 
  (lambda (value) 
    (fun (fun value))))

(define (add1 v)
  (+ 1 v))

(define add2 (double add1))

(add2 1) ; ==> 3

现在合同没有写明,因此您通过(fun ...)来证明fun必须是一个函数来进行扣除。想象一下:

(define test (double 5)) ; probably works OK
(test 1) 

由于您得到application: 5 is not a procedure或类似的东西,最后一个失败。错误消息未标准化。

如何攻击您的任务是通过创建一个与您的函数具有相同自变量的助手,但除此之外,我猜当前的数字应从1开始。如我所展示的,您将function变量用作函数并通过不断增加来递归n呼叫为f时,数字并减少#t。实际函数将通过传递除状态变量之外的所有参数来使用帮助器。

答案 1 :(得分:1)

您的问题需要折叠,这是对其他列表进行迭代同时保留到目前为止已完成的工作的标准方法。

以下是使用for/fold的敲诈方法:

(define (nth-filtered predicate index)
  (for/fold ([count 0]
             [current #f] #:result current)
            ([n (in-naturals 1)]) ; we start at 1 but we could start at 0
            #:break (= count index)
    (values (if (predicate n) (add1 count) count)
            n)))

for/fold列出初始状态。在这里,我们将count定义为给定谓词返回#t的次数,将current作为当前测试的值。

然后它需要一个迭代器列表,在这种情况下,我们只对(in-naturals)进行无限迭代。

为使其停止,我们提供了#:break条件,即“当真实谓词(count)的数量等于请求的数量(index)时的条件。< / p>

for/fold请求其主体以每个“状态”变量的值列表结尾,以便为下一次迭代更新它们。这里我们提供两个值:一个是新的count,另一个是当前的n

您可以尝试一下,它可以按您的要求工作:

> (nth-filtered even? 1)
2
> (require math/number-theory)
> (nth-filtered prime? 10)
29
> (nth-filtered prime? 5)
11