方案 - 定义定义
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)
【讨论】:
以上是关于方案 - 定义定义的主要内容,如果未能解决你的问题,请参考以下文章
Android 屏幕适配屏幕适配通用解决方案 ⑤ ( 自定义组件解决方案 | 自定义 ViewGroup 组件 onMeasure 方法中计算每个子组件坐标数据 | 自定义组件完整代码 )
Android 屏幕适配屏幕适配通用解决方案 ⑤ ( 自定义组件解决方案 | 自定义 ViewGroup 组件 onMeasure 方法中计算每个子组件坐标数据 | 自定义组件完整代码 )