方案 - 定义定义

Posted

技术标签:

【中文标题】方案 - 定义定义【英文标题】:Scheme - defining a definition 【发布时间】:2014-05-30 04:01:15 【问题描述】:

这两天我一直对完成这类问题感到困惑。

生成的函数(由 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

任何对正确方向的帮助都会大有帮助。

【问题讨论】:

【参考方案1】:

试试

(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-indexed,请更改为

(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】:

这种现象称为closure。闭包基本上是makeListPickerFor以函数形式返回的内部状态。将其分配给某个名称 S 会导致 S 成为您可以进行后续调用的函数。然后,此函数可以访问返回它的第一个函数范围内的该内部状态。

【讨论】:

【参考方案3】:

这是另一种定义方式:

(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)

【讨论】:

以上是关于方案 - 定义定义的主要内容,如果未能解决你的问题,请参考以下文章

如何自定义这个已经自定义的 jQuery 排序解决方案?

Android 屏幕适配屏幕适配通用解决方案 ⑤ ( 自定义组件解决方案 | 自定义 ViewGroup 组件 onMeasure 方法中计算每个子组件坐标数据 | 自定义组件完整代码 )

Android 屏幕适配屏幕适配通用解决方案 ⑤ ( 自定义组件解决方案 | 自定义 ViewGroup 组件 onMeasure 方法中计算每个子组件坐标数据 | 自定义组件完整代码 )

我可以在 Phonegap Build 中为 iOS 定义自定义 URL 方案吗?

Swagger 文件安全方案已定义但未使用

使用在方案文件中定义的函数,在另一个方案文件中