试图弄清楚haskell代码的含义

时间:2019-09-26 03:54:14

标签: haskell programming-languages

嘿,我对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))

谢谢

1 个答案:

答案 0 :(得分:4)

要理解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之前对其进行评估。

ELetERec(非递归让和递归让)的方程式很有趣,因为它们所做的只是将ELetERec重写为不同的表达式,然后求值。这是所谓的“语法糖”的一个很好的例子。这些句法形式并不能使语言更具表达力。取而代之的是,它们在“回避”过程中被浅化为基本形式。

如果您还有其他问题,请提出更具体的问题。这些代码很多,所以我无法回答所有问题!