Lambda演算Haskell的Beta转换
我想实现一个函数,该函数对lambda表达式进行beta缩减,其中lambda表达式的类型为:Lambda演算Haskell的Beta转换,haskell,lambda-calculus,Haskell,Lambda Calculus,我想实现一个函数,该函数对lambda表达式进行beta缩减,其中lambda表达式的类型为: data Expr = App Expr Expr | Abs Int Expr | Var Int deriving (Show,Eq) 到目前为止,我的评估职能是: eval1cbv :: Expr -> Expr eval1cbv (Var x) = (Var x) eval1cbv (Abs x e) = (Abs x e) eval1cbv (App (Abs x e1) e@(Ab
data Expr = App Expr Expr | Abs Int Expr | Var Int deriving (Show,Eq)
到目前为止,我的评估职能是:
eval1cbv :: Expr -> Expr
eval1cbv (Var x) = (Var x)
eval1cbv (Abs x e) = (Abs x e)
eval1cbv (App (Abs x e1) e@(Abs y e2)) = eval1cbv (subst e1 x e)
eval1cbv (App e@(Abs x e1) e2) = eval1cbv (subst e2 x e)
eval1cbv (App e1 e2) = (App (eval1cbv e1) e2)
其中subst
是用于定义替换的函数
然而,当我尝试使用beta reduce来减少表达式时,我得到了一个非穷举模式错误,我无法理解为什么。我能做的是在底部添加一个额外的案例,如下所示:
eval :: Expr -> Expr
eval (Abs x e) = (Abs x e)
eval (App (Abs x e1) e@(Abs y e2)) = subst e1 x e
eval (App e@(Abs x e1) e2) = App e (eval e2)
eval (App e1 e2) = App (eval e1) e2
eval (Var x) = Var x
但是,如果我这样做了,那么lambda表达式就不会被缩减,这意味着输入与函数的输出是相同的
因此,如果我尝试评估一个简单的案例,如:
eval (App (Abs 1 (Abs 2 (Var 1))) (Var 3))
评估(应用程序(Abs 2(Var 2))(Abs 3(Var 3)))它工作正常-给出>
Abs 3(变量3)
但是当我为一个更大的测试用例运行它时,比如:
评估(应用程序(Abs 1(Abs 2(Var 1)))(Var 3))我得到:
eval (App (Abs 1 (Abs 2 (Var 1))) (Var 3))
当您尝试将Abs x e
的形式应用于Var y
时,您就在这个分支中
所以你有
这不是你想做的。(Abs x e)
和(Var y)
均为正常形式(即已评估),因此您应该替换。您似乎只处理lambda,而不处理变量
你的代码有更多的问题。考虑这个分支, 结果总是一个
应用程序
。例如,如果eval e1=Abs x E
则结果为App(Abs x E)e2
。它停止在那里,不执行进一步的评估
并考虑这个分支,
如果替换的结果是一个应用术语,会发生什么?结果会被评估吗编辑 关于您的变更,假设
LamApp e1 e2
您之前遵循了价值评估策略(即,您在替换之前正在评估e2
)。那已经过去了
这里它是一个lambda,因此不需要计算
在这里,不管e2是什么,都要进行替换,因此您的操作与之前完全相同。您当时不需要前面的案例,现在正在遵循按姓名呼叫评估策略。我不知道这是不是你想要的。此外,您在这里使用错误的参数调用subst
。我想你的意思是subst e1 x e2
,你不需要@e
这里您只需要评估第一个参数,它与按名称调用策略一致。但我也不知道这是否是你的意图
您是否考虑过该错误可能在函数
subst
中?应用subst
后,您不需要eval
?您还应该提供What'sLamExpr
?非常感谢您的回答!我试着把我的代码改成上面的代码,这样可以稍微减少一点,但不能完全减少。您能看一下并告诉我任何建议的更改吗?:)@JoeBowtie对你的新版本进行了编辑,并发表了一些评论。
App (Abs x e) (Var y)
= App (Abs x e) (eval (Var y))
= App (Abs x e) (Var y)
eval (App e1 e2) = App (eval e1) e2
eval (App (Abs x e1) e@(Abs y e2)) = subst e1 x e
eval1cbv (LamApp (LamAbs x e1) e@(LamAbs y e2)) = eval1cbv (subst e1 x e)
eval1cbv (LamApp e@(LamAbs x e1) e2) = eval1cbv (subst e2 x e)
eval1cbv (LamApp e1 e2) = (LamApp (eval1cbv e1) e2)