haskell实现问题

haskell实现问题,haskell,behavior,language-implementation,Haskell,Behavior,Language Implementation,哈斯克尔是一门非常棒的语言。我喜欢它。但是作为C++程序员,对计算机体系结构有一些基本的了解,我真的想知道Haskell。 我的意思是,例如,map函数。我知道语法,知道结果。然而,我想知道这个函数在RAM中是如何工作的。因为C语言非常清楚语法和计算机行为之间的映射关系 那么,有人对函数式编程语法背后的计算机行为有什么想法吗?或者任何关于“C++对象模型内部”的书籍? < P>实现懒惰函数语言的基本思想被称为图缩减。 “函数式编程语言的实现”是一本关于该主题的详细(如果是较老的话)书籍: 更像教

哈斯克尔是一门非常棒的语言。我喜欢它。但是作为C++程序员,对计算机体系结构有一些基本的了解,我真的想知道Haskell。 我的意思是,例如,
map
函数。我知道语法,知道结果。然而,我想知道这个函数在RAM中是如何工作的。因为C语言非常清楚语法和计算机行为之间的映射关系


那么,有人对函数式编程语法背后的计算机行为有什么想法吗?或者任何关于“C++对象模型内部”的书籍?

< P>实现懒惰函数语言的基本思想被称为图缩减。 “函数式编程语言的实现”是一本关于该主题的详细(如果是较老的话)书籍:

更像教程的介绍:


有关如何实现GHC的更多信息,请参阅“无脊椎无标记G-Machine”(STGM)论文,例如:

首先,警告:Haskell的一个基本属性是编译器极有可能在编译期间对代码执行非常彻底的转换。因此,实际执行的代码可能与您编写的代码完全不同

这是一个警告,对于第一个近似值,您可以期望每个变量和每个数据字段都是指向堆对象的指针。其中一些堆对象表示数据(整数、布尔、字符、列表节点等),而其中一些对象表示由于惰性而尚未执行的Haskell代码。如果编写一个长而复杂的表达式,则每个子表达式都将成为一个堆对象,顶级表达式指向较低的表达式。因此,程序的整个表达式图成为堆上的对象图

(Graph/=tree。树中没有“循环”。Haskell允许递归,因此Haskell表达式不一定是表达式树。)

大型Haskell表达式变成了一大堆堆对象。复杂的嵌套模式匹配将按最佳顺序分解为一系列单层匹配。该语言的所有其他语法都被剥离,直到只剩下6个原语:

  • 创建变量
  • 使用变量
  • 创建函数
  • 调用函数
  • 创建数据记录
  • 检查数据记录
  • 如果您想知道实际的位和字节是如何工作的,这取决于编译器。如果你是指GHC,它的工作原理大致如下:

    • 每个堆对象都是代码或数据

    • 如果它是数据,则它包含一个值构造函数ID号和该构造函数的每个字段的一个指针

    • 如果它是代码(即,一些尚未执行的子表达式),则它包含一个指向函数机器代码块的指针,以及一个指向每个函数参数的指针(无currying)

    • 当您尝试对堆对象执行条件分支、I/O操作或
      seq
      时,运行时会跳转到堆对象指向的某些代码

    • 如果对象表示数据,它将指向一些立即返回的代码

    • 如果对象表示代码,它将指向实际实现该函数的代码。这段代码计算函数的答案,并用表示答案的数据对象覆盖原始堆对象

    • 无论哪种方式,当控件返回给调用方时,heap对象肯定是一个数据对象,它现在可以检查constructor ID或它想做的任何事情


    有一本非常好的书详细介绍了如何使用惰性图缩减实现函数式语言:

    . 西蒙·佩顿·琼斯和大卫·莱斯特,1992年。 这本书提供了一种实用的方法来理解使用惰性图简化的非严格函数语言的实现。这本书旨在成为实用的实验室材料的来源,通过帮助读者开发、修改和实验一些非平凡的编译器,帮助函数式语言实现“活起来”

    这本书与众不同之处在于,它既要被执行,也要被阅读。我们不只是对每种实现技术进行抽象描述,而是提供每种主要方法的完整工作原型的代码,然后对其进行一系列改进。所有代码都以机器可读的形式提供

    注意这本书不同于,
    西蒙·佩顿·琼斯,1987年(这也很有趣)。

    我几乎想知道这是否属于理论计算机科学交流。但我不确定;有人知道吗?@jdevelop非常感谢你,你真的帮了我一个无耻的插件:你可以使用
    ghc heapview
    ghc vis
    包了解值的堆表示。实际上,即使是C也不会告诉你那么多硬件细节,例如,它是完全有效的(如果不常见的话)实现在没有堆栈的情况下运行,并将所有内容放在堆上。毫不奇怪,Haskell避免将其规范更多地固定在任何特定的硬件环境中。所以,实际上,只有将自己局限于给定的编译器和后端,才能回答这个问题。