代码之家  ›  专栏  ›  技术社区  ›  Leonard

初学者:Scheme中的Curried函数

  •  4
  • Leonard  · 技术社区  · 16 年前

    (编辑:我更正了上面的引文……我最初错误地引用了这个定义。)

    任务是定义程序的当前应用程序,该程序的计算结果为3

    (define foo1
        (lambda (x)
            (* x x)))
    

    我真的不明白这里的意思,阅读维基百科上关于Curriying的条目也没有什么帮助。

    有谁能更清楚地解释一下这里的要求?

    事实上,即使给我这个问题的答案也会有帮助,因为在这个问题之后还有五个问题需要解决。。。我只是不明白基本的意思。

    此外:即使在布赖恩·坎贝尔(Brian Campbell)冗长的解释之后,我还是有点迷茫。

    (foo1 (sqrt 3))) 被认为是foo的应用程序,因此是foo的当前应用程序?

    看起来太简单了,但也许。。。

    (((foo1 2 )) 2) into DrScheme给出了以下错误(这是我所期望的)

    procedure application: expected procedure, given: 4 (no arguments)
    

    重读后 What is Currying?

    (define (foo1 a)
        (lambda (b)
            (* a b)))
    

    ((foo1 3 ) 4)
    

    12

    该死的,20年的C编程并没有让我做好准备。:-:-)

    6 回复  |  直到 8 年前
        1
  •  7
  •   Brian Campbell Dennis Williamson    16 年前

    嗯,与通常更清晰的书籍风格相比,这个问题的措辞相当混乱。事实上,如果你是从学校得到习题集,你可能会错误地引用习题集 here ; 这可能会导致你的困惑。

    我将为您详细介绍这个定义,并列举一些可能有助于您了解情况的示例。

    表达式E的应用是形式为(E1…En)的表达式。

    下面是一个应用程序示例:

    (foo 1 2)      ; This is an application of foo
    (bar 1)        ; This is an application of bar
    

    这包括对应于表达式(E)的情况n=0。

    (baz)          ; This is an application of baz
    

    当前的E申请是E申请或当前的E申请。。。。。。。。。。。

    这个定义分为两部分。从第一个开始:

    当前E的应用程序是E的应用程序

    (foo 1 2)       ; (1) A Curried application of foo, since it is an application of foo
    (bar 1)         ; (2) A Curried application of bar, since it is an application of bar
    (baz)           ; (3) A Curried application of baz, since it is an application of baz
    

    或者是一个应用程序的当前应用程序的E

    ((foo 1 2) 3)   ; (4) A Curried application of foo, since it is an application of (1)
    ((bar 1))       ; (5) A Curried application of bar, since it is an application of (2)
    ((baz) 1 2)     ; (6) A Curried application of baz, since it is an application of (3)
    (((foo 1 2) 3)) ; A Curried application of foo, since it is an application of (4)
    (((bar 1)) 2)   ; A Curried application of bar, since it is an application of (5)
                    ; etc...
    

    这是否为您提供了入门所需的帮助?

    编辑 (foo1 (sqrt 3)) 是一个咖喱应用程序 foo1 algebraic numbers

    你的第二个例子确实是一个错误。 foo1 返回一个整数,该整数无效。对于后面的一些示例,函数应用程序的递归情况是有效的。看看 foo3 例如

    :我刚签了SICP,看起来这里的概念直到第1.3节才解释,而本作业只提到了第1.1节。如果您还没有阅读,我建议您尝试阅读第1.3节。

        2
  •  4
  •   Community CDub    8 年前

    看见 What is 'Currying'?

    咖喱具有一种功能并提供 一个新函数接受单个 参数,并返回指定的 函数及其第一个参数集 我同意这一论点。

        3
  •  3
  •   GoZoner    11 年前

    (define-syntax curry
      (syntax-rules ()
        ((_ (a) body ...) 
         (lambda (a) body ...))
        ((_ (a b ...) body ...)
         (lambda (a) (curry (b ...) body ...)))))
    

    然后将其用作:

    > (define adding-n3 (curry (a b c) (+ a b c)))
    > (define adding-n2-to-100 (adding-n3 100))
    > ((adding-n2-to-100) 1) 10)
    111
    
    > (adding-n3 1)
    #<procedure>
    
    > ((adding-n3 1) 10)
    #<procedure>
    
        4
  •  3
  •   ceving    10 年前

    下面是我一直使用的“curry”的一个实现:

    > (define curry (lambda (f . c) (lambda x (apply f (append c x)))))
    > ((curry list 5 4) 3 2)
    (5 4 3 2)
    

    还有一个宏是有人写的,让我们来编写函数,当您调用它们时,如果参数不足,这些函数会隐式地为您使用: http://www.engr.uconn.edu/~jeffm/Papers/curry.html

        5
  •  2
  •   Will Ness Derri Leahy    12 年前

    因此,如果你有:

    (define F (lambda (a b) (+ a b)))
    (F 1 2) ;; ==> 3
    

    你可以用咖喱做成如下的东西:

    (define F (lambda (a) (lambda (b) (+ a b))))
    ((F 1) 2) ;; ==> 3
    

    (foo1 (sqrt 3))
    

    似乎很合适。我建议暂时不要看这本书,多读一些。


    实际上,您可以制作一个函数,为您制作简单的咖喱菜:

    (define (curry f x) (lambda (y) (apply f (cons x y))))
    (curry = 0) ;; a function that returns true if input is zero
    
        6
  •  0
  •   Annonyme    12 年前

    condition-case .

    (condition-case (func)
        ((exn) (print "error")))
    

    (define curry
        (lambda (func . args)
            (condition-case (apply func args)
               ((exn)
                   (lambda plus
                       (apply curry func (append args plus)))))]))))
    

    这有点难看,因为如果你一次使用太多的参数,你永远不会得到最终的结果,但这会把任何函数变成curryd形式。