- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以从我个人的研究来看,闭包/柯里化(Currying)似乎或多或少是完全相同的东西,这不可能是明显正确的。那么区别在哪里呢?
所以这是一个 Racket 中的闭包示例:
(define (make-an-adder x)
(lambda (y)
(+ y x)))
(define add3 (make-an-adder 3))
(add3 5)
会回馈
8
那么柯里化(Currying)的区别在哪里呢?因为如果我查找文档和其他示例,它们似乎与我为闭包展示的完全相同?
先谢谢大家了!
最佳答案
所以它们是不同的概念,但都与嵌套的 lambda 相关。
闭包可以由引用在自身外部定义的变量的 lambda 创建,并且当 lambda 从定义外部变量的上下文中转义时最为重要。闭包的工作是确保在 lambda 转义上下文时保留变量。
Curried 函数是一种可以在多个步骤或多个不同的函数应用程序中获取其参数的函数。这通常意味着 lambda 嵌套在 lambda 中。
大多数有用的柯里化(Currying)函数都需要使用闭包,但如果内部 lambda 忽略外部参数,它们就不是闭包。一个简单的例子:
(define (curried-ignore-first ignored)
(lambda (y) y))
这不是闭包,因为内部 lambda (lambda (y) y)
已经关闭:它不引用自身以外的任何变量。
柯里化(Currying)函数并不总是需要忽略外部参数...它只需要在返回内部 lambda 之前处理它们,这样内部 lambda 就不会引用外部参数。一个简单的例子是柯里化(Currying)的 choose
函数。 choose
的“正常”定义确实使用了闭包:
(define (choose b)
(lambda (x y)
(if b x y))) ; inner lambda refers to `b`, so it needs a closure
但是,如果 if b
放在外层 lambda 之外,我们就可以避免闭包:
(define (choose b)
(if b
(lambda (x y) x) ; not closures, just nested lambdas
(lambda (x y) y)))
当内部 lambda 引用外部上下文中的变量并可能转义该上下文时,需要闭包。外部上下文通常是函数或 lambda,但不一定是。它可以是一个让:
(define closure-with-let
(let ([outer "outer"])
(lambda (ignored) outer))) ; closure because it refers to `outer`
这是一个闭包,但不是柯里化(Currying)的例子。
原题中的例子是产生闭包的柯里化(Currying)函数
(define (make-an-adder x)
(lambda (y)
(+ y x)))
如果你想制作一个仍然是具有相同行为的柯里化(Currying)函数的版本,但在某些特殊情况下不需要对 x
进行闭包,你可以在 lambda 之前分支:
(define (make-an-adder x)
(match x
[0 identity]
[1 add1]
[-1 sub1]
[2 (lambda (y) (+ y 2))]
[3 (lambda (y) (+ y 3))]
[_ (lambda (y) (+ y x))]))
这避免了为 x
是一个精确的整数 -1 到 3 的情况产生一个闭包,但仍然在 x
的所有其他情况下产生一个闭包。如果您将 x
的域限制为一个有限集,您可以将它变成一个不需要闭包的函数,只需枚举所有情况即可。
如果您不想对 x
进行闭包,但对其他事情进行闭包也无妨,您可以使用递归和组合来构造一个不会对结束进行闭包的输出函数x
:
(define (make-an-adder x)
(cond [(zero? x) identity]
[(positive-integer? x)
(compose add1 (make-an-adder (sub1 x)))]
[(negative-integer? x)
(compose sub1 (make-an-adder (add1 x)))]))
请注意,这仍然会产生闭包(因为 compose
在其参数上创建闭包),但它产生的函数不会在 x
上关闭。一旦这个版本的 make-an-adder
产生了它的结果,它就“完成”了处理 x
并且不需要再关闭它。
关于functional-programming - Racket - Closure/Currying,区别在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62499789/
我意识到“强类型”和“软类型”的定义是松散且易于解释的,但我还没有找到关于无类型 Racket (根据我的理解意味着动态类型)和类型 Racket 的明确定义。 再一次,我确定它不是那么简单和干燥,但
我来自 Java 和 Python,很难理解面向对象代码在 Racket 中的工作方式。 给定 (define food% (class object% (super-new) (i
我安装了 Sublime Text - Racket Package,但没有用。出现此错误。我该怎么办。 [Errno 2] No such file or directory: 'racke
.rkt是“常规”Racket 源代码的常规文件扩展名。在文档中,我还看到了 .rktl 和 .rkts 正在使用。什么是.rktl和 .rkts用于,还有我不知道的更多 Racket 文件扩展名吗?
假设我为具有“中心”的集合定义了一个结构体。 (struct centered-set (center elems)) 我想保证以下条件。 elems是一个集合。 center是 elems 的成员(
我想要一个函数,它接受一个字符串,由一个 python 格式的树组成,就像这样 "[0, [1, 0]]" 并输出一个可用的 Racket 列表,像这样 '(0 (1 0)) 我的第一步是将字符串转换
是否有 Racket 内置函数列表?我正在寻找类似 this one 的列表对于 python 。我似乎无法在文档中找到一个。 最佳答案 这里有一些列表: Racket文档中所有函数的索引: http
虽然 Racket 允许创建 GUI 应用程序(甚至游戏),但我想知道它是否适合与 Things 一样在视觉上发布商业应用程序或 OmniOutliner .这样的应用程序会感觉原生还是看起来像一个不
和node的npm一样,我们使用package.json来解决依赖。 我试过raco pkg,它似乎只是一种开发/发布包的方式,而不是解决外部依赖。 最佳答案 如上所述,Racket 中的 info.
我是 Racket 的新手,尽管到目前为止我已经设法使用 servlet 并让一些东西发挥作用。我现在想做的是验证一个简单的用户名/密码 POST 请求。我已经通过“web-server/formle
我正在为现场编码表演创建一个程序,为此我需要一个基本的 S 表达式代码编辑器(我输入的内容将在适当的语法上下文中评估为 Racket 代码)。 由于 DrRacket 本身是用 Racket 编写的,
和node的npm一样,我们使用package.json来解决依赖。 我试过raco pkg,它似乎只是一种开发/发布包的方式,而不是解决外部依赖。 最佳答案 如上所述,Racket 中的 info.
我正在尝试在 Racket 中编写模块元语言 mylang ,它接受将修改后的主体传递给的第二种语言,例如: (module foo mylang typed/racket body) 相当于: (m
我没有运气找到一种方法来按照我想要的方式进行这项工作,所以如果有人能提供帮助,我将不胜感激。 我想要的是能够在终端上做到这一点: > racket 然后能够输入 Racket 命令并让它们编译。像,
我来自 Java 世界,对 Racket 充满热情。 想知道类似Maven的工具在哪里。如果你不熟悉Maven,还有Scala中的SBT,Android中的gradle,Elixir中的mix等,作为
在 typed/racket 我有一个像 [(? procedure? p ) (apply p xv*)]会导致错误: Type Checker: Function has no cases in:
我是 Lisp-scheme 的新手,对整个函数范式还很陌生,我目前正在做一个任务,要求我重载一个名称相同但参数集不同的函数 racket .下面是我试图实现的一个例子: #lang racket (
有没有办法在 Racket 中获取对象的唯一标识符?例如,当我们使用 Racket 的 eq?运算符来检查两个变量是否指向同一个对象,它使用什么标识符来实现这种比较? 我正在寻找类似 python 的
当我在 Dr. Racket 或从命令行运行我的测试时,失败的测试总是在一行上。 例如, (bad (interp-t-prog (list '(class posn extends object (
我有以下代码: (plot (function sin (- pi) pi #:label "y = sin(x)")) 但是在解决 SICP 时我没有遇到这样的结构:#:label "y = sin
我是一名优秀的程序员,十分优秀!