package normalorder import "git.maximhutz.com/max/lambda/pkg/lambda" // ReduceOnce attempts to apply a single reduction to a lambda expression. // It returns (1) the final expression (reduced, or not), and (2) whether or not // a reduction was applied. // // If a reduction is not applied, it returns the original expression. func ReduceOnce(e lambda.Expression) (lambda.Expression, bool) { switch e := e.(type) { case lambda.Abstraction: body, reduced := ReduceOnce(e.Body) if reduced { return lambda.Abstraction{Parameter: e.Parameter, Body: body}, true } return e, false case lambda.Application: if fn, fnOk := e.Abstraction.(lambda.Abstraction); fnOk { return fn.Body.Substitute(fn.Parameter, e.Argument), true } abs, reduced := ReduceOnce(e.Abstraction) if reduced { return lambda.Application{Abstraction: abs, Argument: e.Argument}, true } arg, reduced := ReduceOnce(e.Argument) if reduced { return lambda.Application{Abstraction: e.Abstraction, Argument: arg}, true } return e, false default: return e, false } }