3

阅读 Haskell.Happy 文档并实现 'let' 运算符

 Exp : let var '=' Exp in Exp              { \p -> $6 (($2,$4 p):p) }

文档说它是“一个接受变量值环境并返回表达式计算值的函数:”

无法理解语法的实际含义,这些构造在 Haskell 中是如何调用的?

编辑:我的意思是这些

\p -> $6 (($2,$4 p):p)
4

2 回答 2

5

let类似 ML 的语言(例如 Haskell)中的表达式只是引入了局部变量绑定:

magnitude x y =
  let xs = x * x in
  let ys = y * y in
  sqrt (xs + ys)

Happy 文档正在讨论为假设的类 ML 语言实现解析器。Happy 语法中的$n变量指的是当前规则中匹配的事物的索引:

let var '=' Exp in Exp
1   2   3   4   5  6

花括号中的表达式是该规则匹配时生成的代码。

所以\p -> $6 (($2,$4 p):p)给你一个 lambda,它接受一个变量 environment p,它是一对名称和值的列表。lambda 的主体由在 中$6评估的第二个表达式解析 ( )p以及名称 ( ) 与在当前环境 ( ) 中$2评估第一个表达式解析 ( ) 所产生的值之间的关联组成。$4$4 p

于 2014-06-19T03:08:44.627 回答
2

基本上,p诸如[("x",4),("y",5)]定义变量值xy. 当您评估可能涉及此类变量的表达式时,结果取决于p. 这由\p -> ....

例如,我们可以期待类似的东西

Exp + Exp    { \p -> $1 p + $2 p }

表示使用由 定义的相同变量值来评估这两个术语的事实p

现在,let它很奇特,因为它定义了一个新变量,给它一个值。为了表达这个事实,我们需要p用新的关联来改变它。

let var =  Exp in Exp
$1  $2  $3 $4  $5 $6

给定p,$4 的值$4 p就像我们在前面的 sum 示例中所做的一样(我们假设var$4 中不可见,也就是说,我们不允许var递归定义)。写

value_of_$4 = $4 p

但是,$6 的值不是$6 p因为 $6 必须“看到”新定义的var. 所以我们写

value_of_$6 = $6 (p augmented with the association <<var = value_of_$4>>)

那是

value_of_$6 = $6 ( ($2,value_of_$4) : p )

那是

value_of_$6 = $6 ( ($2, $4 p) : p )

所以我们最终得到

let var =  Exp in Exp    { \p -> $6 ( ($2, $4 p) : p ) }
$1  $2  $3 $4  $5 $6
于 2014-06-19T12:20:09.573 回答