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

时间:2011-04-03 18:23:54

标签: haskell currying internal-representation partial-application

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

3 个答案:

答案 0 :(得分:10)

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

请参阅boxed data上的此问题和how thunks are represented上的GHC手册。

答案 1 :(得分:7)

以这种方式思考:所有由一大块代码(“thunk”)表示,必须直接调用才能获得结果。当你写一个文字1时,它被编译成一个代码块,在调用时返回1(实际上是fromIntegral 1),然后用那块代码代替文字1。懒惰也是关键:不是立即计算某些东西,而是创建一个thunk,当被调用时将进行计算。如果将该表达式传递给另一个函数,则它是传递的包装器thunk,因此除非需要明确检查其结果,否则计算不会发生。

在Haskell中,函数应用程序的表示方式相同:一个thunk处理一个参数并返回一个thunk,它处理下一个参数或产生结果。所以(1+)是函数应用程序(+) 1(+)是一个thunk,它希望传递一个数字并返回一个期望传递另一个数字的thunk。由于(+)是严格的,第二个thunk实际上是添加而不是返回必须被调用以进行实际添加的thunk。所以(1+)计算到第二个thunk,需要使用maplist上迭代时提供的另一个数字来调用。

答案 2 :(得分:3)

您可能还想查看Simon Peyton Jones和David Lester的书Implementing Functional Languages: A Tutorial