- Change Abstraction, Application, and Variable to use private fields with getter methods - Return value types instead of pointers from constructors - Update all type switches to match value types instead of pointer types - Remove pointer equality optimizations (not applicable with immutable values) - Return empty set instead of nil from GetFreeVariables default case
33 lines
671 B
Go
33 lines
671 B
Go
package lambda
|
|
|
|
func ReduceOnce(e Expression) (Expression, bool) {
|
|
switch e := e.(type) {
|
|
case Abstraction:
|
|
body, reduced := ReduceOnce(e.Body())
|
|
if reduced {
|
|
return NewAbstraction(e.Parameter(), body), true
|
|
}
|
|
return e, false
|
|
|
|
case Application:
|
|
if fn, fnOk := e.Abstraction().(Abstraction); fnOk {
|
|
return Substitute(fn.Body(), fn.Parameter(), e.Argument()), true
|
|
}
|
|
|
|
abs, reduced := ReduceOnce(e.Abstraction())
|
|
if reduced {
|
|
return NewApplication(abs, e.Argument()), true
|
|
}
|
|
|
|
arg, reduced := ReduceOnce(e.Argument())
|
|
if reduced {
|
|
return NewApplication(e.Abstraction(), arg), true
|
|
}
|
|
|
|
return e, false
|
|
|
|
default:
|
|
return e, false
|
|
}
|
|
}
|