【发布时间】:2019-05-07 16:35:31
【问题描述】:
我想实现一个函数,它对 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))) 它工作正常 -> 绝对值 3(变量 3)
但是当我为更大的测试用例运行它时:
eval (App (Abs 1 (Abs 2 (Var 1))) (Var 3)) 我得到:
- 如果我使用第一个函数而不添加最后一个案例,则不是详尽的模式
- 或完全相同的表达式 App (Abs 1 (Abs 2 (Var 1))) (Var 3),如果我添加最后一种情况,显然不会减少
谁能帮我解决这个问题? :)
【问题讨论】:
-
您是否考虑过错误可能出在您的函数
subst中?在申请subst之后,您还不需要eval吗?您还应该提供minimal, complete and verifiable example -
LamExpr是什么?