【发布时间】:2012-09-11 00:43:24
【问题描述】:
我想通过以下方式使用此代码: 如果我输入:
((function1 5) 2)
其中 function1 基于5 执行其过程,并返回一个基于2 执行某些内容的function2。这可以吗?
【问题讨论】:
标签: function functional-programming lisp scheme currying
我想通过以下方式使用此代码: 如果我输入:
((function1 5) 2)
其中 function1 基于5 执行其过程,并返回一个基于2 执行某些内容的function2。这可以吗?
【问题讨论】:
标签: function functional-programming lisp scheme currying
(define (multiplyBy n) (lambda (x) (* n x)))
((multiplyBy 5) 2)
我相信会做你想做的事。
【讨论】:
11.2.1 和11.4.2 部分所做内容的扩展。 (define) [第三种形式] 将一些形式和主体分配给变量名;主体恰好是一个返回函数的 lambda 表达式。 lambda 部分指定“在计算 lambda 表达式时有效的环境被记住为过程的一部分”。这意味着在执行时,首先使用其参数评估 define'd 变量,然后将它们传递到 Lamba 的环境(保存在结果过程中)。
继续@zebediah49 的示例,这是另一种方法:
(define (multiplyBy n) ((curry *) n))
((multiplyBy 5) 2)
> 10
一般来说,对于一个有两个参数的函数(上面的例子看起来有点不同,因为* 是一个有一个或多个参数的函数):
(define (function1 arg0) (curry <function2, receives arg1> arg0))
引用curry 过程的文档:
返回一个过程,它是
proc的柯里化版本。当第一次应用生成的过程时,除非给定它可以接受的最大参数数量,否则结果是一个接受附加参数的过程
基本上,您被要求实现currying。引用维基百科的文章:
在数学和计算机科学中,柯里化是一种转换具有多个参数(或参数的 n 元组)的函数的技术,它可以被称为一个函数链,每个函数都有一个参数(部分应用)。它由 Moses Schönfinkel 提出,后来被 Haskell Curry 重新发现。因此,有人说将其命名为 schönfinkeling 更为正确。
请注意,所有这些都是等价的:
(define ((function1 arg0) arg1) <body>)
(define (function1 arg0) (lambda (arg1) <body>))
(define (function1 arg0) (curry <function2, receives arg1> arg0))
(define (function1 arg0) (define (function2 arg1) <body>) function2)
【讨论】:
我问了一圈,发现你可以这样定义一个函数:
(define ((function1 arg0) arg1) (;procedure here...))
这就是我想要的。我想毕竟它并没有真正得到一个函数来返回一个过程......:/感谢所有的帮助! :)
【讨论】:
(define ((function1 arg0) arg1) <body>) 是 (define (function1 arg0) (lambda (arg1) <body>)) 的语法糖,两个版本在底层是相同的
其中许多答案正确地显示了从函数返回函数的不同方式。更一般地说,您正在做的事情称为 Currying。更具体地说,“currying”是指将一个接受 n 个参数的函数转换为一个接受一个参数并返回一个接受 n-1 个参数的新函数的过程。
对于初学者来说,这是我觉得最好看的风格:
#lang racket
;; a curried function that multiplies two numbers
(define (function1 arg0)
(define (function2 arg1)
(* arg0 arg1))
function2)
此函数接受一个参数 (arg0),定义一个参数 (arg1) 的新函数,该函数将 arg0 和 arg1 相乘,然后返回。
这个不像使用 lambda 的那么短,但是当你刚开始时,lambda 看起来只是一件更奇怪的东西,没有任何意义。
【讨论】: