From cc0c6cc420ca8019665e745797758c997cc35358 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Fri, 16 Aug 2019 22:33:16 +0200 Subject: Use generic Shift/Subst impls --- dhall/src/core/thunk.rs | 35 +++------- dhall/src/core/value.rs | 168 +++++++++++----------------------------------- dhall/src/core/var.rs | 175 ++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 186 insertions(+), 192 deletions(-) (limited to 'dhall/src') diff --git a/dhall/src/core/thunk.rs b/dhall/src/core/thunk.rs index e315a90..b6358ef 100644 --- a/dhall/src/core/thunk.rs +++ b/dhall/src/core/thunk.rs @@ -266,24 +266,16 @@ impl TypedThunk { impl Shift for Thunk { fn shift(&self, delta: isize, var: &AlphaVar) -> Option { - Some( - self.0 - .borrow() - .shift(delta, var)? - .into_thunk(self.1.shift(delta, var)?), - ) + Some(Thunk(self.0.shift(delta, var)?, self.1.shift(delta, var)?)) } } impl Shift for ThunkInternal { fn shift(&self, delta: isize, var: &AlphaVar) -> Option { Some(match self { - ThunkInternal::PartialExpr(e) => ThunkInternal::PartialExpr( - e.traverse_ref_with_special_handling_of_binders( - |v| Ok(v.shift(delta, var)?), - |x, v| Ok(v.shift(delta, &var.under_binder(x))?), - )?, - ), + ThunkInternal::PartialExpr(e) => { + ThunkInternal::PartialExpr(e.shift(delta, var)?) + } ThunkInternal::ValueF(m, v) => { ThunkInternal::ValueF(*m, v.shift(delta, var)?) } @@ -301,27 +293,16 @@ impl Shift for TypedThunk { impl Subst for Thunk { fn subst_shift(&self, var: &AlphaVar, val: &Typed) -> Self { - self.0 - .borrow() - .subst_shift(var, val) - .into_thunk(self.1.subst_shift(var, val)) + Thunk(self.0.subst_shift(var, val), self.1.subst_shift(var, val)) } } impl Subst for ThunkInternal { fn subst_shift(&self, var: &AlphaVar, val: &Typed) -> Self { match self { - ThunkInternal::PartialExpr(e) => ThunkInternal::PartialExpr( - e.map_ref_with_special_handling_of_binders( - |v| v.subst_shift(var, val), - |x, v| { - v.subst_shift( - &var.under_binder(x), - &val.under_binder(x), - ) - }, - ), - ), + ThunkInternal::PartialExpr(e) => { + ThunkInternal::PartialExpr(e.subst_shift(var, val)) + } ThunkInternal::ValueF(_, v) => { // The resulting value may not stay in normal form after substitution ThunkInternal::ValueF(WHNF, v.subst_shift(var, val)) diff --git a/dhall/src/core/value.rs b/dhall/src/core/value.rs index 0f2ef00..da70118 100644 --- a/dhall/src/core/value.rs +++ b/dhall/src/core/value.rs @@ -287,12 +287,9 @@ impl Shift for ValueF { t.shift(delta, var)?, e.shift(delta, &var.under_binder(x))?, ), - ValueF::AppliedBuiltin(b, args) => ValueF::AppliedBuiltin( - *b, - args.iter() - .map(|v| Ok(v.shift(delta, var)?)) - .collect::>()?, - ), + ValueF::AppliedBuiltin(b, args) => { + ValueF::AppliedBuiltin(*b, args.shift(delta, var)?) + } ValueF::Pi(x, t, e) => ValueF::Pi( x.clone(), t.shift(delta, var)?, @@ -313,80 +310,27 @@ impl Shift for ValueF { ValueF::EmptyListLit(tth) => { ValueF::EmptyListLit(tth.shift(delta, var)?) } - ValueF::NEListLit(elts) => ValueF::NEListLit( - elts.iter() - .map(|v| Ok(v.shift(delta, var)?)) - .collect::>()?, - ), - ValueF::RecordLit(kvs) => ValueF::RecordLit( - kvs.iter() - .map(|(k, v)| Ok((k.clone(), v.shift(delta, var)?))) - .collect::>()?, - ), - ValueF::RecordType(kvs) => ValueF::RecordType( - kvs.iter() - .map(|(k, v)| Ok((k.clone(), v.shift(delta, var)?))) - .collect::>()?, - ), - ValueF::UnionType(kts) => ValueF::UnionType( - kts.iter() - .map(|(k, v)| { - Ok(( - k.clone(), - v.as_ref() - .map(|v| Ok(v.shift(delta, var)?)) - .transpose()?, - )) - }) - .collect::>()?, - ), - ValueF::UnionConstructor(x, kts) => ValueF::UnionConstructor( - x.clone(), - kts.iter() - .map(|(k, v)| { - Ok(( - k.clone(), - v.as_ref() - .map(|v| Ok(v.shift(delta, var)?)) - .transpose()?, - )) - }) - .collect::>()?, - ), + ValueF::NEListLit(elts) => { + ValueF::NEListLit(elts.shift(delta, var)?) + } + ValueF::RecordLit(kvs) => ValueF::RecordLit(kvs.shift(delta, var)?), + ValueF::RecordType(kvs) => { + ValueF::RecordType(kvs.shift(delta, var)?) + } + ValueF::UnionType(kts) => ValueF::UnionType(kts.shift(delta, var)?), + ValueF::UnionConstructor(x, kts) => { + ValueF::UnionConstructor(x.clone(), kts.shift(delta, var)?) + } ValueF::UnionLit(x, v, kts) => ValueF::UnionLit( x.clone(), v.shift(delta, var)?, - kts.iter() - .map(|(k, v)| { - Ok(( - k.clone(), - v.as_ref() - .map(|v| Ok(v.shift(delta, var)?)) - .transpose()?, - )) - }) - .collect::>()?, - ), - ValueF::TextLit(elts) => ValueF::TextLit( - elts.iter() - .map(|contents| { - use InterpolatedTextContents::{Expr, Text}; - Ok(match contents { - Expr(th) => Expr(th.shift(delta, var)?), - Text(s) => Text(s.clone()), - }) - }) - .collect::>()?, + kts.shift(delta, var)?, ), + ValueF::TextLit(elts) => ValueF::TextLit(elts.shift(delta, var)?), ValueF::Equivalence(x, y) => { ValueF::Equivalence(x.shift(delta, var)?, y.shift(delta, var)?) } - ValueF::PartialExpr(e) => ValueF::PartialExpr( - e.traverse_ref_with_special_handling_of_binders( - |v| Ok(v.shift(delta, var)?), - |x, v| Ok(v.shift(delta, &var.under_binder(x))?), - )?, - ), + ValueF::PartialExpr(e) => ValueF::PartialExpr(e.shift(delta, var)?), }) } } @@ -395,32 +339,17 @@ impl Subst for ValueF { fn subst_shift(&self, var: &AlphaVar, val: &Typed) -> Self { match self { // Retry normalizing since substituting may allow progress - ValueF::AppliedBuiltin(b, args) => apply_builtin( - *b, - args.iter().map(|v| v.subst_shift(var, val)).collect(), - ), + ValueF::AppliedBuiltin(b, args) => { + apply_builtin(*b, args.subst_shift(var, val)) + } // Retry normalizing since substituting may allow progress ValueF::PartialExpr(e) => { - normalize_one_layer(e.map_ref_with_special_handling_of_binders( - |v| v.subst_shift(var, val), - |x, v| { - v.subst_shift( - &var.under_binder(x), - &val.under_binder(x), - ) - }, - )) + normalize_one_layer(e.subst_shift(var, val)) } // Retry normalizing since substituting may allow progress - ValueF::TextLit(elts) => { - ValueF::TextLit(squash_textlit(elts.iter().map(|contents| { - use InterpolatedTextContents::{Expr, Text}; - match contents { - Expr(th) => Expr(th.subst_shift(var, val)), - Text(s) => Text(s.clone()), - } - }))) - } + ValueF::TextLit(elts) => ValueF::TextLit(squash_textlit( + elts.iter().map(|contents| contents.subst_shift(var, val)), + )), ValueF::Lam(x, t, e) => ValueF::Lam( x.clone(), t.subst_shift(var, val), @@ -447,42 +376,25 @@ impl Subst for ValueF { ValueF::EmptyListLit(tth) => { ValueF::EmptyListLit(tth.subst_shift(var, val)) } - ValueF::NEListLit(elts) => ValueF::NEListLit( - elts.iter().map(|v| v.subst_shift(var, val)).collect(), - ), - ValueF::RecordLit(kvs) => ValueF::RecordLit( - kvs.iter() - .map(|(k, v)| (k.clone(), v.subst_shift(var, val))) - .collect(), - ), - ValueF::RecordType(kvs) => ValueF::RecordType( - kvs.iter() - .map(|(k, v)| (k.clone(), v.subst_shift(var, val))) - .collect(), - ), - ValueF::UnionType(kts) => ValueF::UnionType( - kts.iter() - .map(|(k, v)| { - (k.clone(), v.as_ref().map(|v| v.subst_shift(var, val))) - }) - .collect(), - ), - ValueF::UnionConstructor(x, kts) => ValueF::UnionConstructor( - x.clone(), - kts.iter() - .map(|(k, v)| { - (k.clone(), v.as_ref().map(|v| v.subst_shift(var, val))) - }) - .collect(), - ), + ValueF::NEListLit(elts) => { + ValueF::NEListLit(elts.subst_shift(var, val)) + } + ValueF::RecordLit(kvs) => { + ValueF::RecordLit(kvs.subst_shift(var, val)) + } + ValueF::RecordType(kvs) => { + ValueF::RecordType(kvs.subst_shift(var, val)) + } + ValueF::UnionType(kts) => { + ValueF::UnionType(kts.subst_shift(var, val)) + } + ValueF::UnionConstructor(x, kts) => { + ValueF::UnionConstructor(x.clone(), kts.subst_shift(var, val)) + } ValueF::UnionLit(x, v, kts) => ValueF::UnionLit( x.clone(), v.subst_shift(var, val), - kts.iter() - .map(|(k, v)| { - (k.clone(), v.as_ref().map(|v| v.subst_shift(var, val))) - }) - .collect(), + kts.subst_shift(var, val), ), ValueF::Equivalence(x, y) => ValueF::Equivalence( x.subst_shift(var, val), diff --git a/dhall/src/core/var.rs b/dhall/src/core/var.rs index 3af12ec..8d02171 100644 --- a/dhall/src/core/var.rs +++ b/dhall/src/core/var.rs @@ -92,43 +92,6 @@ impl Shift for AlphaVar { } } -impl Shift for () { - fn shift(&self, _delta: isize, _var: &AlphaVar) -> Option { - Some(()) - } -} - -impl Shift for Option { - fn shift(&self, delta: isize, var: &AlphaVar) -> Option { - Some(match self { - None => None, - Some(x) => Some(x.shift(delta, var)?), - }) - } -} - -impl Shift for Box { - fn shift(&self, delta: isize, var: &AlphaVar) -> Option { - Some(Box::new(self.as_ref().shift(delta, var)?)) - } -} - -impl Subst for () { - fn subst_shift(&self, _var: &AlphaVar, _val: &S) -> Self {} -} - -impl> Subst for Option { - fn subst_shift(&self, var: &AlphaVar, val: &S) -> Self { - self.as_ref().map(|x| x.subst_shift(var, val)) - } -} - -impl> Subst for Box { - fn subst_shift(&self, var: &AlphaVar, val: &S) -> Self { - Box::new(self.as_ref().subst_shift(var, val)) - } -} - /// Equality up to alpha-equivalence impl std::cmp::PartialEq for AlphaVar { fn eq(&self, other: &Self) -> bool { @@ -188,3 +151,141 @@ impl From for Label { x.0 } } +impl Shift for () { + fn shift(&self, _delta: isize, _var: &AlphaVar) -> Option { + Some(()) + } +} + +impl Shift for Option { + fn shift(&self, delta: isize, var: &AlphaVar) -> Option { + Some(match self { + None => None, + Some(x) => Some(x.shift(delta, var)?), + }) + } +} + +impl Shift for Box { + fn shift(&self, delta: isize, var: &AlphaVar) -> Option { + Some(Box::new(self.as_ref().shift(delta, var)?)) + } +} + +impl Shift for std::rc::Rc { + fn shift(&self, delta: isize, var: &AlphaVar) -> Option { + Some(std::rc::Rc::new(self.as_ref().shift(delta, var)?)) + } +} + +impl Shift for std::cell::RefCell { + fn shift(&self, delta: isize, var: &AlphaVar) -> Option { + Some(std::cell::RefCell::new(self.borrow().shift(delta, var)?)) + } +} + +impl Shift for dhall_syntax::ExprF { + fn shift(&self, delta: isize, var: &AlphaVar) -> Option { + Some(self.traverse_ref_with_special_handling_of_binders( + |v| Ok(v.shift(delta, var)?), + |x, v| Ok(v.shift(delta, &var.under_binder(x))?), + )?) + } +} + +impl Shift for Vec { + fn shift(&self, delta: isize, var: &AlphaVar) -> Option { + Some( + self.iter() + .map(|v| Ok(v.shift(delta, var)?)) + .collect::>()?, + ) + } +} + +impl Shift for HashMap +where + K: Clone + std::hash::Hash + Eq, +{ + fn shift(&self, delta: isize, var: &AlphaVar) -> Option { + Some( + self.iter() + .map(|(k, v)| Ok((k.clone(), v.shift(delta, var)?))) + .collect::>()?, + ) + } +} + +impl Shift for dhall_syntax::InterpolatedTextContents { + fn shift(&self, delta: isize, var: &AlphaVar) -> Option { + use dhall_syntax::InterpolatedTextContents::{Expr, Text}; + Some(match self { + Expr(x) => Expr(x.shift(delta, var)?), + Text(s) => Text(s.clone()), + }) + } +} + +impl Subst for () { + fn subst_shift(&self, _var: &AlphaVar, _val: &S) -> Self {} +} + +impl> Subst for Option { + fn subst_shift(&self, var: &AlphaVar, val: &S) -> Self { + self.as_ref().map(|x| x.subst_shift(var, val)) + } +} + +impl> Subst for Box { + fn subst_shift(&self, var: &AlphaVar, val: &S) -> Self { + Box::new(self.as_ref().subst_shift(var, val)) + } +} + +impl> Subst for std::rc::Rc { + fn subst_shift(&self, var: &AlphaVar, val: &S) -> Self { + std::rc::Rc::new(self.as_ref().subst_shift(var, val)) + } +} + +impl> Subst for std::cell::RefCell { + fn subst_shift(&self, var: &AlphaVar, val: &S) -> Self { + std::cell::RefCell::new(self.borrow().subst_shift(var, val)) + } +} + +impl, E: Clone> Subst for dhall_syntax::ExprF { + fn subst_shift(&self, var: &AlphaVar, val: &S) -> Self { + self.map_ref_with_special_handling_of_binders( + |v| v.subst_shift(var, val), + |x, v| v.subst_shift(&var.under_binder(x), &val.under_binder(x)), + ) + } +} + +impl> Subst for Vec { + fn subst_shift(&self, var: &AlphaVar, val: &S) -> Self { + self.iter().map(|v| v.subst_shift(var, val)).collect() + } +} + +impl> Subst for dhall_syntax::InterpolatedTextContents { + fn subst_shift(&self, var: &AlphaVar, val: &S) -> Self { + use dhall_syntax::InterpolatedTextContents::{Expr, Text}; + match self { + Expr(x) => Expr(x.subst_shift(var, val)), + Text(s) => Text(s.clone()), + } + } +} + +impl> Subst for HashMap +where + K: Clone + std::hash::Hash + Eq, +{ + fn subst_shift(&self, var: &AlphaVar, val: &S) -> Self { + self.iter() + .map(|(k, v)| (k.clone(), v.subst_shift(var, val))) + .collect() + } +} -- cgit v1.2.3