部分应用程序在运行时如何表示?

发布于 2024-10-29 23:25:12 字数 181 浏览 1 评论 0原文

当我在 Haskell 中编写类似 map (1+) list 的内容时,(1+) 的内部表示是什么?由于它是 (+) 的部分应用,因此参数 1 必须保存在某个地方,但我无法理解这一点。有人能给我一个简短的解释,柯里化和部分应用是如何实现的吗?

When I write something like map (1+) list in Haskell, what is the internal representation of (1+)? Since it is a partial application of (+), the argument 1 has to be saved somewhere, but I can't get my head around this. Can somebody give me a brief explanation, how currying and partial application is implemented?

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

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

发布评论

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

评论(3

哭了丶谁疼 2024-11-05 23:25:12

部分应用的函数(实际上,Haskell 堆中的几乎所有其他内容)都表示为闭包——一种结合了代码指针和参数槽的结构。具体来说,我们将未完全评估形式的值称为thunk

请参阅之前关于盒装数据 以及关于如何表示 thunk 的 GHC 手册。

Partially applied functions (and, indeed, pretty much everything else in the Haskell heap) are represented as closures -- a structure combining a code pointer, and argument slots. Specifically, we call values that are not in a fully evaluated form thunks.

See this earlier question on boxed data and the GHC manual on how thunks are represented.

诗化ㄋ丶相逢 2024-11-05 23:25:12

可以这样想:一切都由必须直接调用才能获得结果的一段代码(“thunk”)表示。当您编写文字 1 时,它会被编译为一段代码,在调用时返回 1(实际上是 fromIntegral 1),然后将该代码块用于文字 1 的位置。这也是惰性的关键:不是立即计算某些内容,而是创建一个 thunk,在调用时将执行计算。如果将该表达式传递给另一个函数,则传递的是包装器 thunk,因此计算不会发生,直到/除非需要显式检查其结果。

在 Haskell 中,函数应用程序以相同的方式表示:一个 thunk 处理一个参数并返回一个 thunk,该 thunk 处理下一个参数或生成结果。所以 (1+) 是函数应用 (+) 1(+) 是一个 thunk,期望传递一个数字,并且返回一个 thunk,希望传递另一个数字。由于 (+) 是严格的,因此第二个 thunk 实际上执行加法,而不是返回必须调用才能执行实际加法的 thunk。因此,(1+) 计算为第二个 thunk,需要使用另一个数字来调用,该数字将在迭代 listmap 提供>。

Think of it this way: everything is represented by a chunk of code (a "thunk") that has to be invoked directly to get a result. When you write a literal 1, it gets compiled to a chunk of code that returns 1 (actually, fromIntegral 1) when invoked, and that chunk of code is then used in place of the literal 1. This is also key to laziness: instead of calculating something immediately, a thunk is created that when invoked will do the calculation. If you pass that expression to another function, it's the wrapper thunk that's passed, and so the calculation doesn't happen until/unless something needs to explicitly examine its result.

In Haskell, function applications are represented the same way: a thunk that processes one parameter and returns a thunk that either processes the next parameter or produces the result. So (1+) is the function application (+) 1: (+) is a thunk that expects to be passed a single number and returns a thunk that expects to be passed another single number. Since (+) is strict, that second thunk actually does the addition instead of returning a thunk that has to be invoked to do the actual addition. So (1+) evaluates to that second thunk, which needs to be invoked with another number which will be supplied by map as it iterates over list.

孤独患者 2024-11-05 23:25:12

您可能还想查看实现函数式语言:教程,西蒙·佩顿·琼斯和大卫·莱斯特所著的书。

You may also want to check out Implementing Functional Languages: A Tutorial, a book by Simon Peyton Jones and David Lester.

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