与 ML 中的闭包相关的资源?

发布于 2024-12-15 02:15:45 字数 253 浏览 4 评论 0原文

我正在上一门使用 ML 的课程,我们将讨论闭包,但我不太理解它们,尤其是在 ML 中。我在课堂上做了笔记,但它们对我来说没有多大意义/提供了足够的细节。我尝试在网上查找更多信息,但找不到任何信息。

有谁知道有关 ML 中的闭包(或一般的 ML/闭包)的任何非常好的资源吗?

或者,如果有人可以发布一些关于如何在 ML 中实现闭包或 ML 中的闭包是什么样子、闭包是什么等的一般想法/解释,我将非常感激。我只是想理解闭包的概念/用途。

提前致谢!

I'm taking a class that uses ML, and we're going over closures, but I don't quite understand them, especially in ML. I took notes in class and they don't make much sense to me / provide enough detail. I tried looking around online for more info but couldn't find any.

Does anyone know of any resources about closures in ML (or about ML / closures in general) that are pretty good?

Or if someone can post a few general thoughts / explanations on how to implement a closure in ML or how a closure in ML would look like, what a closure is, etc. I'd really appreciate it. I'm just trying to understand the concept / use of closures.

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

給妳壹絲溫柔 2024-12-22 02:15:45

我不懂机器学习,所以我的答案是Scheme,这是另一种函数式编程语言。我假设你不了解Scheme,并且会很好地注释我的代码。

**注意:Scheme 是动态类型的,因此您不会看到任何类型声明(如 int、float、char 等)。

(define (double x)       ;this defines a new function called "double" which takes one argument called x
   (* 2 x))              ;return 2 times its argument. Function application in Scheme takes the form (function arg1 arg2 ...)

我们将像这样使用这个新定义的函数:

(double 10)  ;returns 20
(double 8)   ;returns 16

在这个函数中,变量x是一个局部变量x 是 double 的形式参数。每当我们在 double 主体中使用 x 时,我们所指的值就毫无疑问。但是这样呢:

(define (foo x)          ;define a function "foo" which takes on argument called x
   (* x a))              ;return x times a

再次强调,x 是一个形式参数。但是a呢?当我们在 foo 的主体中使用 a 时,我们意味着什么? a 未在 foo 中定义,因此称为自由变量。要了解 a 的含义,我们必须看看 foo 之外的情况。例如,假设 foo 是在此上下文中定义的:

(define (bar a)        ;define a function "bar" which takes one argument called "a"
   (define (foo x)     ;define "foo" as an inner function of bar
      (* x a)))        ;foo returns x * a

现在我们知道 a 的含义。方案(以及机器学习)是词法范围的,这意味着要找出变量a的含义,我们需要查看文本上下文(希望这是有意义的)。

现在,上面的 bar 定义实际上是不正确的:即使 foo 返回某些内容,bar 也不会返回任何内容。它将 foo 定义为内部函数,但该定义后面没有任何语句。让我们解决这个问题:

(define (bar a)        ;define a function "bar" which takes one argument called "a"
   (define (foo x)     ;define "foo" as an inner function of bar
      (* x a))         ;foo returns x * a
   foo)                ;bar returns the function foo

现在,bar 返回函数foo。我们刚刚将 bar 转换为高阶函数,因为它返回另一个函数。

但有一个问题。通常,当bar返回时,不再需要局部变量a,并且它的值丢失。但 foo 仍然引用 a!所以a需要再坚持一段时间。这就是闭包的用武之地。a 的值是“封闭的”,因此只要函数 foo 存在,它就会一直存在。这样,即使在 bar 执行完毕后,我们也可以调用 foo 。现在,让我们重命名 foobar 来看看为什么这是有用的:

(define (make-multiplier a)
   (define (multiplier x)
      (* x a))
   multiplier)

现在,我们可以这样做:

(define triple (make-multiplier 3))   ;call make-multiplier with the value 3. Bind the function which is returned to the variable "triple."
(triple 5)                            ;call triple with the value 5. Since the 3 was "closed over", (triple 5) returns 5 * 3, which is 15.

所以 - 当一个函数有一个“自由变量”时,闭包就是为函数创建,它“关闭”自由变量并在函数的生命周期内保留它。这样,当函数被传递并离开它定义的上下文时,“自由变量”仍然有效。

I don't know any ML, so my answer will be in Scheme, which is another functional programming language. I'll assume that you don't know Scheme, and will comment my code well.

**Note: Scheme is dynamically typed, so you won't see any type declarations (like int, float, char, etc.).

(define (double x)       ;this defines a new function called "double" which takes one argument called x
   (* 2 x))              ;return 2 times its argument. Function application in Scheme takes the form (function arg1 arg2 ...)

We would use this newly defined function like this:

(double 10)  ;returns 20
(double 8)   ;returns 16

In this function, the variable x is a local variable. x is a formal parameter of double. Whenever we use x in the body of double, there is no doubt as to what value we mean. But what about this:

(define (foo x)          ;define a function "foo" which takes on argument called x
   (* x a))              ;return x times a

Once again, x is a formal parameter. But what about a? What do we mean when we use a in the body of foo? a is not defined in foo, so it is called a free variable. To see what a means, we have to look outside foo. For example, suppose that foo was defined in this context:

(define (bar a)        ;define a function "bar" which takes one argument called "a"
   (define (foo x)     ;define "foo" as an inner function of bar
      (* x a)))        ;foo returns x * a

Now we know what a means. Scheme (and also ML) is lexically-scoped, which means that to find out what the variable a means, we look at the textual context (hopefully this makes sense).

Now, the above definition of bar is actually incorrect: even thought foo returns something, bar doesn't return anything. It defines foo as an inner function, but then there is no statement following that definition. Let's fix that:

(define (bar a)        ;define a function "bar" which takes one argument called "a"
   (define (foo x)     ;define "foo" as an inner function of bar
      (* x a))         ;foo returns x * a
   foo)                ;bar returns the function foo

Now, bar returns the function foo. We have just turned bar into a higher-order function, because it returns another function.

But there's a problem. Normally, when bar returns, the local variable a is no longer needed, and its value is lost. But foo still makes a reference to a! So a needs to stick around for a while longer. This is where closures come in. The value of a is "closed over", so it sticks around for as long as the function foo exists. That way, we can call foo even after bar has finished execution. Now, let's rename foo and bar to see why this is useful:

(define (make-multiplier a)
   (define (multiplier x)
      (* x a))
   multiplier)

Now, we can do this:

(define triple (make-multiplier 3))   ;call make-multiplier with the value 3. Bind the function which is returned to the variable "triple."
(triple 5)                            ;call triple with the value 5. Since the 3 was "closed over", (triple 5) returns 5 * 3, which is 15.

So - when a function has a "free variable", a closure is created for the function which "closes over" the free variable and preserves it for the lifetime of the function. That way, when the function is passed around and leaves the context it was defined in, the "free variable" continues to be valid.

你另情深 2024-12-22 02:15:45

闭包是 ML(或 Ocaml、Scheme、Lisp)中实现函数的含义。所以所有函数都是闭包(即代码和数据的混合)。例如(使用 Ocaml 语法)

 (* function making an incrementer, returning a function *)
 let make_incr i = fun x -> x + i;;

 (* use it to define the successor function *)
 let succ = make_incr 1;;

 (* compute the successor of 4 *)
 succ 4;;

ocaml 解释器当然会成功回答,

val make_incr : int -> int -> int = <fun>
val succ : int -> int = <fun>
 - : int = 5

您会看到 make_incr 是一个高阶函数:给定一些整数,它会生成一个新函数。因此,在上面的示例中,给定 1,它会生成 succsucc 包含加法代码和整数 1。因此它混合了代码和整数 1。闭包中的数据(封闭变量的环境)。

阅读更多关于闭包的维基百科条目,以及任何好的教科书:SICP(Sussman 着),或者 C.Queinnec Lisp in Small Pieces,或者任何关于 Ocaml 的好的介绍性书籍,或者 Appel 的书“Compiling with Continuations”等等。

closures are the mean in ML (or in Ocaml, Scheme, Lisp) to implement functions. So all functions are closures (that is, a mix of code and data). For example (using Ocaml syntax)

 (* function making an incrementer, returning a function *)
 let make_incr i = fun x -> x + i;;

 (* use it to define the successor function *)
 let succ = make_incr 1;;

 (* compute the successor of 4 *)
 succ 4;;

The ocaml interpreter is of course answering successfully

val make_incr : int -> int -> int = <fun>
val succ : int -> int = <fun>
 - : int = 5

you see that make_incr is a high-order function: given some integer it produces a new function. So given 1 it produces succ in the above example. And succ contains both the addition code, and the integer 1. So it mixes code & data (the environment for closed variables) in a closure.

Read more Wikipedia's entry on closure, and any good textbook: the SICP (by Sussman), or C.Queinnec Lisp in Small Pieces, or any good introductory book on Ocaml, or Appel's book "Compiling with Continuations", etc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文