过去两天我一直对完成这类问题感到困惑。
生成的函数(通过makeMixer)将整数N作为输入,并输出原始列表中的第N个项目。例如,如果makeListPickerFor按如下方式调用:
(makeListPickerFor '(4 0 -2 -3 5))
将生成一个函数,该函数将整数作为输入,例如3, 并返回列表中的该项(对于3,它将输出-2,因为-2 是原始列表中的第3项。)
因此,如果原始呼叫如下:
(define S (makeListPickerFor '(4 0 -2 -3 5)))
然后生成的函数S表现如下:
(S 4) *** would return -3, because -3 is the 4th item in the original list
(S 2) *** would return 0, because 0 is the 2nd item in the original list
任何正确方向的帮助都会有很大帮助。
答案 0 :(得分:1)
这种现象称为closure。闭包基本上是makeListPickerFor
以函数形式返回的内部状态。将其分配给某个名称S
会导致S
成为您可以进行后续调用的函数。然后,此函数可以在返回它的第一个函数的范围内访问该内部状态。
答案 1 :(得分:0)
尝试
(define (makeListPickerFor l)
(lambda (n)
(list-ref l n)))
所以makeListPickerFor
返回一个仍然可以通过闭包访问初始列表l
的函数。然后
> (define S (makeListPickerFor '(4 0 -2 -3 5)))
> (S 4)
5
> (S 2)
-2
请注意,在Scheme列表中,索引为0索引,因此结果如此。如果要使用1索引,请更改为
(define (makeListPickerFor l)
(lambda (n)
(list-ref l (- n 1))))
> (define S (makeListPickerFor '(4 0 -2 -3 5)))
> (S 4)
-3
> (S 2)
0
该程序也可以表示为
(define makeListPickerFor
(lambda (l)
(lambda (n)
(list-ref l (- n 1)))))
这与前一个过程完全相同,因为(define (f x))
是(define f (lambda (x)))
的语法糖,但更清楚它是一个返回过程的过程。
答案 2 :(得分:0)
以下是另一种定义它的方法:
(define (make-picker lst)
(define (picker n)
(list-ref lst (- n 1)))
picker)
(define list-len 10000000)
(define f (make-picker (range list-len 0 -1)) ; range is #!racket specific
(f 1) ; ==> 10000000
(f list-len) ; ==> 1
对于#!racket:
中非常大的列表,这是一个更有效的方法(define (make-picker-hash lst)
(define hash
(make-immutable-hasheqv (map cons
(range 1 (add1 (length lst)))
lst)))
(lambda (x)
(hash-ref hash x)))
(define fh (make-picker-hash (range list-len 0 -1)))
(fh list-len) ; ==> 1
(fh 1) ; ==> 10000000 (list-len)