7

当我在Haskell中写入类似map (1+) list的东西时,(1+)的内部表示是什么?由于它是(+)的部分应用,所以参数1必须保存在某个地方,但我无法理解这一点。有人可以给我一个简单的解释,如何实施咖啡和部分应用?部分应用程序在运行时如何表示?

+0

您是否了解关闭(如何实现lambda函数)? '(1+)'只是说'(\ x - > 1 + x)'的简短方式。 – 2011-04-03 18:36:20

+0

是的。但是我想知道,编译器如何将类似的东西翻译成机器代码/无论如何。 – fuz 2011-04-03 18:37:27

+1

如果你对这些东西感兴趣,我强烈建议你阅读[PLAI](http://www.cs.brown.edu/~sk/Publications/Books/ProgLangs/2007-04-26/)。虽然它是Scheme而不是Haskell,但核心思想是一样的。尤其请参阅第8章:实现Laizness并注意他们如何处理'closureV'值类型。 – 2011-04-04 04:58:33

回答

2

您可能还想看看Implementing Functional Languages: A Tutorial,一本由Simon Peyton Jones和David Lester编写的书。

+0

我在哪里可以得到它? – fuz 2011-04-04 17:10:37

+0

不知道。几年前我从当地的大学图书馆借了它,但我不认为这是一种选择。 无论如何,如果你能掌握它,我强烈建议你这样做。这是一个非常轻量级的文本,也是功能语言实现的非常好的介绍。 – 2011-04-04 17:16:05

+1

现在看起来有一个在线版本,该书已绝版:http://research.microsoft.com/en-us/um/people/simonpj/Papers/pj-lester-book/ – 2011-04-04 17:18:17

6

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

在Haskell中,函数应用程序以相同的方式表示:一个thunk处理一个参数并返回一个thunk,该thunk处理下一个参数或产生结果。所以(1+)是功能应用程序(+) 1(+)是一个thunk,希望传递一个单一的数字并返回一个thunk,期望通过另一个单一的数字。由于(+)是严格的,那第二个thunk实际上做了加法,而不是返回一个必须被调用来执行实际加法的thunk。因此(1+)评估为第二个thunk,需要用map提供的另一个数字调用,因为它在list上迭代。

+0

这是做到这一点的一种方式,但它绝不是唯一的方法。 – augustss 2011-04-03 23:09:46

+1

@augustss:因此“用这种方式思考”。 – geekosaur 2011-04-03 23:13:06

9

部分应用函数(实际上几乎所有Haskell堆中的其他东西)都被表示为闭包 - 一个结合了代码指针和参数槽的结构。具体而言,我们将未完全评估的值称为thunks

boxed data上查看此早期问题,并在how thunks are represented上查看GHC手册。

+0

启发。谢谢! – fuz 2011-04-04 12:48:33

相关问题