Skip to content

Instantly share code, notes, and snippets.

@Thiez
Forked from anonymous/gist:a9c9c1c028d69e3b7219
Last active August 29, 2015 14:16
Show Gist options
  • Save Thiez/1adac91aff54c997f355 to your computer and use it in GitHub Desktop.
Save Thiez/1adac91aff54c997f355 to your computer and use it in GitHub Desktop.
It just keeps getting better. Now with box patterns.
#![feature(box_patterns)]
pub enum Expression {
Identifier(String),
Function(String, Box<Expression>),
Application(Box<Expression>, Box<Expression>),
}
impl Expression {
fn is_variable_free(&self, var: &str) -> bool {
match *self {
Expression::Identifier(ref id) => var != *id,
Expression::Application(ref lhs, ref rhs) => {
lhs.is_variable_free(var) || rhs.is_variable_free(var)
},
Expression::Function(ref param, ref body) => {
var == *param && body.is_variable_free(var)
},
}
}
pub fn eta_reduce(&mut self) {
use std::mem::swap;
let mut tmp = None;
match self {
&mut Expression::Application(ref mut lhs, ref mut rhs) => {
lhs.eta_reduce();
rhs.eta_reduce();
},
&mut Expression::Function(ref param, box ref mut body) => {
body.eta_reduce();
if let &mut Expression::Application(box ref mut lhs, box Expression::Identifier(ref id)) = body {
if param == id && !lhs.is_variable_free(id) {
tmp = Some(Expression::Identifier(String::new()));
swap(lhs, tmp.as_mut().unwrap());
}
}
},
_ => {},
}
if let Some(ref mut new_self) = tmp { swap(self, new_self) }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment