diff options
author | Nadrieril | 2019-04-12 16:33:49 +0200 |
---|---|---|
committer | Nadrieril | 2019-04-12 16:33:49 +0200 |
commit | 35e19e0f7c3dcfcd4203a3aaaa73d6f26db276f5 (patch) | |
tree | da5c9d6e936ba97d7ccadc213ea2c5a197ebe15b /dhall_core/src/core.rs | |
parent | 7ba857a96eebbdd1cef0aa22407c870887d24aed (diff) | |
parent | 5fcc7f69c7a68b08ff223217e8af9f8edb2cc761 (diff) |
Merge branch 'lifetimes'
Closes #55
Diffstat (limited to '')
-rw-r--r-- | dhall_core/src/core.rs | 134 |
1 files changed, 70 insertions, 64 deletions
diff --git a/dhall_core/src/core.rs b/dhall_core/src/core.rs index d2ecf53..5b138b8 100644 --- a/dhall_core/src/core.rs +++ b/dhall_core/src/core.rs @@ -296,7 +296,7 @@ impl<S, A> Expr<S, A> { let recurse = |e: &SubExpr<S, A>| -> Result<SubExpr<S, B>, Err> { Ok(e.as_ref().traverse_embed(map_embed)?.roll()) }; - self.as_ref().traverse( + self.traverse_ref( |e| recurse(e), |_, e| recurse(e), |x| Ok(S::clone(x)), @@ -331,8 +331,8 @@ impl<N: Clone, E> Expr<N, E> { ) -> SubExpr<N, E2> { match self.as_ref() { ExprF::Embed(e) => f(e), - e => e - .map( + _ => self + .map_ref( |e| e.as_ref().squash_embed(f), |_, e| e.as_ref().squash_embed(f), N::clone, @@ -392,8 +392,8 @@ impl<SE, L, N, E> ExprF<SE, L, N, E> { } } - pub fn traverse<SE2, L2, N2, E2, Err, F1, F2, F3, F4, F5>( - self, + fn traverse_ref<'a, SE2, L2, N2, E2, Err, F1, F2, F3, F4, F5>( + &'a self, map_subexpr: F1, map_under_binder: F2, map_note: F3, @@ -403,21 +403,21 @@ impl<SE, L, N, E> ExprF<SE, L, N, E> { where L: Ord, L2: Ord, - F1: FnMut(SE) -> Result<SE2, Err>, - F2: FnOnce(&L, SE) -> Result<SE2, Err>, - F3: FnOnce(N) -> Result<N2, Err>, - F4: FnOnce(E) -> Result<E2, Err>, - F5: FnMut(L) -> Result<L2, Err>, + F1: FnMut(&'a SE) -> Result<SE2, Err>, + F2: FnOnce(&'a L, &'a SE) -> Result<SE2, Err>, + F3: FnOnce(&'a N) -> Result<N2, Err>, + F4: FnOnce(&'a E) -> Result<E2, Err>, + F5: FnMut(&'a L) -> Result<L2, Err>, { let mut map = map_subexpr; - fn vec<T, U, Err, F: FnMut(T) -> Result<U, Err>>( - x: Vec<T>, + fn vec<'a, T, U, Err, F: FnMut(&'a T) -> Result<U, Err>>( + x: &'a Vec<T>, f: F, ) -> Result<Vec<U>, Err> { - x.into_iter().map(f).collect() + x.iter().map(f).collect() } - fn opt<T, U, Err, F: FnOnce(T) -> Result<U, Err>>( - x: Option<T>, + fn opt<'a, T, U, Err, F: FnOnce(&'a T) -> Result<U, Err>>( + x: &'a Option<T>, f: F, ) -> Result<Option<U>, Err> { Ok(match x { @@ -425,23 +425,23 @@ impl<SE, L, N, E> ExprF<SE, L, N, E> { None => None, }) } - fn btmap<K, L, T, U, Err, FK, FV>( - x: BTreeMap<K, T>, + fn btmap<'a, K, L, T, U, Err, FK, FV>( + x: &'a BTreeMap<K, T>, mut fk: FK, mut fv: FV, ) -> Result<BTreeMap<L, U>, Err> where K: Ord, L: Ord, - FK: FnMut(K) -> Result<L, Err>, - FV: FnMut(T) -> Result<U, Err>, + FK: FnMut(&'a K) -> Result<L, Err>, + FV: FnMut(&'a T) -> Result<U, Err>, { x.into_iter().map(|(k, v)| Ok((fk(k)?, fv(v)?))).collect() } use crate::ExprF::*; Ok(match self { - Var(V(l, n)) => Var(V(map_label(l)?, n)), + Var(V(l, n)) => Var(V(map_label(l)?, *n)), Lam(l, t, b) => { let b = map_under_binder(&l, b)?; Lam(map_label(l)?, map(t)?, b) @@ -456,14 +456,14 @@ impl<SE, L, N, E> ExprF<SE, L, N, E> { } App(f, args) => App(map(f)?, vec(args, map)?), Annot(x, t) => Annot(map(x)?, map(t)?), - Const(k) => Const(k), - Builtin(v) => Builtin(v), - BoolLit(b) => BoolLit(b), - NaturalLit(n) => NaturalLit(n), - IntegerLit(n) => IntegerLit(n), - DoubleLit(n) => DoubleLit(n), - TextLit(t) => TextLit(t.traverse(map)?), - BinOp(o, x, y) => BinOp(o, map(x)?, map(y)?), + Const(k) => Const(*k), + Builtin(v) => Builtin(*v), + BoolLit(b) => BoolLit(*b), + NaturalLit(n) => NaturalLit(*n), + IntegerLit(n) => IntegerLit(*n), + DoubleLit(n) => DoubleLit(*n), + TextLit(t) => TextLit(t.traverse_ref(map)?), + BinOp(o, x, y) => BinOp(*o, map(x)?, map(y)?), BoolIf(b, t, f) => BoolIf(map(b)?, map(t)?, map(f)?), EmptyListLit(t) => EmptyListLit(map(t)?), NEListLit(es) => NEListLit(vec(es, map)?), @@ -483,8 +483,8 @@ impl<SE, L, N, E> ExprF<SE, L, N, E> { }) } - pub fn map<SE2, L2, N2, E2, F1, F2, F3, F4, F5>( - self, + pub fn map_ref<'a, SE2, L2, N2, E2, F1, F2, F3, F4, F5>( + &'a self, mut map_subexpr: F1, map_under_binder: F2, map_note: F3, @@ -494,13 +494,13 @@ impl<SE, L, N, E> ExprF<SE, L, N, E> { where L: Ord, L2: Ord, - F1: FnMut(SE) -> SE2, - F2: FnOnce(&L, SE) -> SE2, - F3: FnOnce(N) -> N2, - F4: FnOnce(E) -> E2, - F5: FnMut(L) -> L2, + F1: FnMut(&'a SE) -> SE2, + F2: FnOnce(&'a L, &'a SE) -> SE2, + F3: FnOnce(&'a N) -> N2, + F4: FnOnce(&'a E) -> E2, + F5: FnMut(&'a L) -> L2, { - trivial_result(self.traverse( + trivial_result(self.traverse_ref( |x| Ok(map_subexpr(x)), |l, x| Ok(map_under_binder(l, x)), |x| Ok(map_note(x)), @@ -509,33 +509,6 @@ impl<SE, L, N, E> ExprF<SE, L, N, E> { )) } - pub fn map_ref<'a, SE2, L2, N2, E2, F1, F2, F3, F4, F5>( - &'a self, - map_subexpr: F1, - map_under_binder: F2, - map_note: F3, - map_embed: F4, - map_label: F5, - ) -> ExprF<SE2, L2, N2, E2> - where - L: Ord, - L2: Ord, - F1: FnMut(&'a SE) -> SE2, - F2: FnOnce(&'a L, &'a SE) -> SE2, - F3: FnOnce(&'a N) -> N2, - F4: FnOnce(&'a E) -> E2, - F5: FnMut(&'a L) -> L2, - { - // Not optimal: reallocates all the Vecs and BTreeMaps for nothing. - self.as_ref().map( - map_subexpr, - |l, e| map_under_binder(*l, e), - map_note, - map_embed, - map_label, - ) - } - pub fn map_ref_simple<'a, SE2, F1>( &'a self, map_subexpr: F1, @@ -567,7 +540,7 @@ impl<SE, L, N, E> ExprF<SE, L, N, E> { E: Clone, F1: Fn(&'a SE) -> Result<SE2, Err>, { - self.as_ref().traverse( + self.traverse_ref( &map_subexpr, |_, e| map_subexpr(e), |x| Ok(N::clone(x)), @@ -670,6 +643,39 @@ impl<N: Clone> SubExpr<N, X> { } } +impl<E: Clone> SubExpr<X, E> { + pub fn note_absurd<N>(&self) -> SubExpr<N, E> { + rc(self.as_ref().map_ref( + |e| e.note_absurd(), + |_, e| e.note_absurd(), + |_| unreachable!(), + E::clone, + Label::clone, + )) + } +} + +impl<E: Clone> Expr<X, E> { + pub fn note_absurd<N: Clone>(&self) -> Expr<N, E> { + self.roll().note_absurd().unroll() + } +} + +impl<N: Clone, E: Clone> SubExpr<N, E> { + pub fn unnote(&self) -> SubExpr<X, E> { + match self.as_ref() { + ExprF::Note(_, e) => e.unnote(), + e => rc(e.map_ref( + |e| e.unnote(), + |_, e| e.unnote(), + |_| unreachable!(), + E::clone, + Label::clone, + )), + } + } +} + impl<N: Clone> Expr<N, X> { // This is all very sad and I hope this can be avoided sometime pub fn absurd_rec<T>(&self) -> Expr<N, T> { |