嘿,我对haskell还是很陌生,我似乎不太了解这部分代码的内容
execCBN :: Program -> Exp
execCBN (Prog e) = evalCBN e
evalCBN :: Exp -> Exp
evalCBN (EApp e1 e2) = case (evalCBN e1) of
(EAbs i e1') -> evalCBN (subst i e2 e1')
e1' -> EApp e1' e2
evalCBN (EIf e1 e2 e3 e4) = if (evalCBN e1) == (evalCBN e2) then evalCBN e3 else evalCBN e4
evalCBN (ELet i e1 e2) = evalCBN (EApp (EAbs i e2) e1)
evalCBN (ERec i e1 e2) = evalCBN (EApp (EAbs i e2) (EFix (EAbs i e1))
感谢
要了解Haskell代码,通常首先要看一下类型!您尚未在此处包括它们,但它们可能看起来像这样:
newtype Program = Program Exp
data Exp
= EApp Exp Exp
| EAbs String Exp
| EIf Exp Exp Exp Exp
| ELet String Exp Exp
| ERec String Exp Exp
| EFix Exp
| EVar String
我肯定是在猜测Exp
类型的一些细节!
现在,这是怎么回事。这为基于lambda演算的非常简单的编程语言定义了抽象语法树。 Exp
的每个构造器都是该语言中的某种语法构造:函数应用程序(EApp
),lambda(EAbs
),if语句(EIf
),依此类推。 evalCBN
函数正在为该编程语言定义解释器或评估器。因为有许多不同的语法构造,所以evalCBN
是用pattern matching定义的,其中每种语法节点都有一个不同的等式,可能需要评估。因为树结构是递归的,所以评估函数也是递归的。
[名称evalCBN
大概是指它是在使用“按需致电”策略而不是“按值致电”策略进行评估的事实。您可以在应用函数的方程式中看到这一点:
evalCBN (EApp e1 e2) = case (evalCBN e1) of
(EAbs i e1') -> evalCBN (subst i e2 e1')
e1' -> EApp e1' e2
[注意,根本不评估参数e2
。相反,它只是以其未赋值的形式替换为表达式e1'
。值变异调用将在替换前评估e2
。
ELet
和ERec
的方程式(非递归让和递归让步)很有趣,因为它们所做的只是将ELet
或ERec
重写为另一个表达式,然后对其求值。这是所谓的“语法糖”的一个很好的例子。这些句法形式并不能使语言更具表达力。相反,它们在“回避”过程中被浅表重写为更基本的形式。
如果您还有其他问题,请问更具体的问题。这些代码很多,所以我无法回答所有问题!