Lambda演算Haskell的Beta转换

时间:2018-12-06 02:16:09

标签: 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@(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缩减来简化表达式时,出现了一个非穷举的模式错误,我无法理解为什么。我要解决的办法是在底部添加一个额外的字母,例如:

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 2(Var 2))(Abs 3(Var 3)))效果很好-> Abs 3(Var 3)

但是当我为更大的测试用例运行它时:

eval(App(Abs 1(Abs 2(Var 1)))(Var 3))我得到:

  1. 如果我不使用最后一种情况而使用第一个功能,则为非穷举模式
  2. 或完全相同的App(Abs 1(Abs 2(Var 1)))(Var 3)表达式,如果加上最后一种情况,显然不会减少

有人可以帮我解决这个问题吗? :)

1 个答案:

答案 0 :(得分:2)

  

但是当我为更大的测试用例运行它时:

eval (App (Abs 1 (Abs 2 (Var 1))) (Var 3)) 

当您尝试将Abs x e形式的内容应用于Var y时,您就在此分支中,

eval (App e@(Abs x e1) e2) = App e (eval e2)

所以你有

  App (Abs x e) (Var y)
= App (Abs x e) (eval (Var y))
= App (Abs x e) (Var y)

这不是您想要的。 (Abs x e)(Var y)均为正常形式(即已评估),因此您应该替换。您似乎只将lambda视为变量,而不将变量视为已评估变量。


您的代码还有更多问题。考虑这个分支,

eval (App e1 e2) = App (eval e1) e2

结果始终是App。例如。如果eval e1 = Abs x e,则结果为App (Abs x e) e2。到此为止,不进行进一步评估。

考虑这个分支

eval (App (Abs x e1) e@(Abs y e2)) = subst e1 x e

如果替换的结果是一个应用程序术语,会发生什么?会评估结果吗?


编辑

关于您的更改,给定LamApp e1 e2,您之前遵循的是按值致电评估策略(即您在替换前评估e2)。没了,

这里e2是lambda,因此不需要评估,

eval1cbv (LamApp (LamAbs x e1) e@(LamAbs y e2)) = eval1cbv (subst e1 x e)

无论如何e2都是在这里替换,因此与以前完全相同。那时您不需要前一种情况,现在正在遵循“按名称致电”评估策略。不知道那是不是你想要的另外,您在此处用错误的参数调用subst。我想您的意思是subst e1 x e2,而您不需要@e

eval1cbv (LamApp e@(LamAbs x e1) e2) =  eval1cbv (subst e2 x e)  

在这里,您只是在评估第一个参数,该参数与按名称调用策略一致。但是我不知道那不是你的意图。

eval1cbv (LamApp e1 e2) = (LamApp (eval1cbv e1) e2)