TL; DR Лямбда-выражение является простым, если (и только если) его тело простое.
Лямбда-выражение в некотором смысле является просто частным случаем операторного выражения, за исключением того, что семантика операции закодирована в грамматике. Вы можете представить, например, разделение OpExp
на несколько c случаев с указанием оператора:
data Exp = IntExp Integer
| VarExp String
| LamExp String Exp
| IfExp Exp Exp Exp
<b> | AddExp Exp Exp -- x + y
| MulExp Exp Exp -- x * y
| AndExpr Exp Exp -- x && y
| ...</b>
| AppExp Exp Exp
Но у нас нет отдельных правил для каждого оператора; у нас есть только один, который хранит рассматриваемый оператор как данные.
Вы можете развить эту идею дальше, рассматривая лямбда-выражение как просто еще один вид выражения оператора.
data Exp = IntExp Integer
| VarExp String
| IfExp Exp Exp Exp
| OpExp Exp Exp
| AppExp Exp Exp
где лямбда выражение типа λx . x + 3
становится
OpExp "λ" (VarExp "x") (OpExp "+" (VarExp "x") (IntExp 3))
(точно так же, как оба аргумента для +
или *
должны быть IntExp
s или выражения, которые оцениваются как IntExp
s, λ
требует первым аргументом должно быть VarExp
. Это ограничения semanti c, которые просто не захватываются самой грамматикой.)
В этом случае определение isSimple
для OpExp
по-прежнему сохраняется : выражение является простым, если связанная переменная (первый аргумент) и тело (второй аргумент) просты.
Таким образом, кажется вполне разумным определить
isSimple (LamExp _ e) = isSimple e