Haskell 哈斯克尔';让';实施
阅读Haskell.Happy文档并实现'let'运算符Haskell 哈斯克尔';让';实施,haskell,happy,Haskell,Happy,阅读Haskell.Happy文档并实现'let'运算符 Exp : let var '=' Exp in Exp { \p -> $6 (($2,$4 p):p) } 文档称它是“一个函数,它接受一个可变值的环境,并返回表达式的计算值:” 无法理解语法的实际含义,这些结构在Haskell中是如何调用的 编辑:我是说这些 \p -> $6 (($2,$4 p):p) 类ML语言(如Haskell)中的let表达式只引入了一个局部变量绑定: magnit
Exp : let var '=' Exp in Exp { \p -> $6 (($2,$4 p):p) }
文档称它是“一个函数,它接受一个可变值的环境,并返回表达式的计算值:”
无法理解语法的实际含义,这些结构在Haskell中是如何调用的
编辑:我是说这些
\p -> $6 (($2,$4 p):p)
类ML语言(如Haskell)中的
let
表达式只引入了一个局部变量绑定:
magnitude x y =
let xs = x * x in
let ys = y * y in
sqrt (xs + ys)
Happy docs正在讨论为假设的类似ML的语言实现解析器。Happy语法中的$n
变量指的是在当前规则中匹配的事物的索引:
let var '=' Exp in Exp
1 2 3 4 5 6
大括号中的表达式是在该规则匹配时生成的代码
因此,
\p->$6(($2,$4p):p)
提供了一个lambda,它接受一个变量环境p
,它是一个名称和值对的列表。lambda的主体包括在p
中计算的第二个解析表达式($6
),以及名称($2
)和在当前环境中计算第一个解析表达式($4
)所得到的值($4 p
)之间的关联,环境p
如[(“x”,4),(“y”,5)]
定义变量x
和y
的值。当计算可能包含此类变量的表达式时,结果取决于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的值只是4p
,正如我们在前面的求和示例中所做的那样(我们假设var
在$4中不可见,也就是说,我们不允许递归定义var
)。写
但是,$6的值不是$6p
,因为$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
$4p、($2,$4p)和():p的语法从何而来?Happy有自己特殊的非Haskell语法,它们引用模式中的第2、第4和第6个值。例如,Exp
Exp:let var'='Exp-in-Exp
中的let
是$1
,=/code>是$2等。这意味着$6(($2,$4p):p)`计算为{2nd Exp}(({var},{1st Exp}p):p)
。注意第一个表达式对变量p
的正常Haskell函数应用,以及列表cons syntax:
@ThomasM.DuBuisson我知道模式中的值,但无法理解{2nd exp}应用于(({var},{1st exp}应用于p):p)背后的逻辑。第二个经验值适用于tupple吗?第二个表达式,$6
被应用于列表someElem:p
,其中someElem
实际上是一个由$2
和$4p
组成的元组(将$4
应用于p
)。奇怪的是,如果你不了解haskell,那你为什么学习起来很开心?
let var = Exp in Exp { \p -> $6 ( ($2, $4 p) : p ) }
$1 $2 $3 $4 $5 $6