Я предполагаю, что ваш тип Term
определен следующим образом:
type Var = String
data Term = Var Var | Lambda Var Term | App Term Term deriving Show
То есть это приложение захвачено конструктором двоичных данных App
.
Теперь обратите внимание, что Ваше определение abstractions
можно упростить, отбросив различие в регистре от второго предложения (случай для пустого хвоста уже пойман первым предложением):
abstractions :: Term -> [Var] -> Term
abstractions t [] = t
abstractions t (x : xs) = Lambda x (abstractions t xs)
Где лямбда-абстракции обычно расширяются как как можно дальше вправо, т. е. лямбда-х1. лямбда х2. т = лямбда х1. (лямбда x2. t) , приложение функции обычно ассоциируется слева, т.е. t u1 u2 = (t u1) u2 . Следовательно, простое применение вашей функции applications
может быть:
applications :: Term -> [Term] -> Term
applications t [] = t
applications t (u : us) = applications (App t u) us
Например:
> applications (Var "x") [Var "y", Var "z"]
App (App (Var "x") (Var "y")) (Var "z")
Теперь, наконец, abstractions
и applications
следуют знакомым шаблонам. abstractions
можно записать в виде правого сгиба по списку переменных для абстрагирования, а applications
можно записать в виде левого сгиба по списку терминов, к которому необходимо применить:
abstractions = foldr Lambda
applications = foldl App