, но когда я запускаю его для более крупного теста, например:
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)
находятся в нормальной форме (т.е. оценены), поэтому вы должны были заменить.Похоже, вы рассматриваете только лямбды, а не переменные, как оцененные.
С вашим кодом больше проблем.Рассмотрим эту ветку,
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
- лямбда, поэтому не нужно оценивать,
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)