diff options
| author | Arnaud Bailly <arnaud.bailly@iohk.io> | 2024-09-24 18:03:35 +0200 |
|---|---|---|
| committer | Arnaud Bailly <arnaud.bailly@iohk.io> | 2024-09-24 18:09:49 +0200 |
| commit | 28ae5ded8bf38dba8b439fce58e525d092633ec3 (patch) | |
| tree | 6b8b0d392c1258f00d23ce7c671761012037d285 | |
| parent | 530fc2be095873b2cdc112216459c462e3e4b462 (diff) | |
| download | lambda-nantes-28ae5ded8bf38dba8b439fce58e525d092633ec3.tar.gz | |
Fix (naive) substitution under lambda
| -rw-r--r-- | rust/src/lambda.rs | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/rust/src/lambda.rs b/rust/src/lambda.rs index 9964021..2ad69f7 100644 --- a/rust/src/lambda.rs +++ b/rust/src/lambda.rs @@ -16,22 +16,23 @@ pub fn run(arg: &str) -> String { fn interpret(arg: &Value) -> Value { match arg { - Value::App(l, r) => apply(l, r), + Value::App(l, r) => apply(&interpret(l), r), other => other.clone(), } } fn apply(l: &Value, r: &Value) -> Value { if let Value::Lam(v, body) = l { - subst(r, v, body) + subst(v, body, r) } else { Value::App(Box::new(l.clone()), Box::new(r.clone())) } } -fn subst(r: &Value, v: &str, body: &Value) -> Value { - match r { - Value::Sym(x) if x == v => body.clone(), +fn subst(var: &str, body: &Value, r: &Value) -> Value { + match body { + Value::Sym(x) if x == var => r.clone(), + Value::Lam(x, b) => Value::Lam(x.to_string(), Box::new(subst(var, b, r))), other => other.clone(), } } @@ -51,4 +52,10 @@ mod lambda_test { let value = parse("((lam x x) 12)"); assert_eq!(Value::Num(12), interpret(&value)); } + + #[test] + fn substitution_occurs_within_abstraction_body() { + let value = parse("(((lam x (lam y x)) 13) 12)"); + assert_eq!(Value::Num(13), interpret(&value)); + } } |
