【问题标题】: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

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

【问题讨论】:

    标签: scheme racket


    【解决方案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)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-04-18
          • 2020-09-21
          • 2014-04-02
          • 2011-02-26
          • 2012-06-15
          • 2011-04-30
          • 2014-10-22
          • 2011-12-14
          相关资源
          最近更新 更多