summaryrefslogtreecommitdiff
path: root/dhall_core
diff options
context:
space:
mode:
Diffstat (limited to 'dhall_core')
-rw-r--r--dhall_core/src/core.rs126
-rw-r--r--dhall_core/src/text.rs22
2 files changed, 102 insertions, 46 deletions
diff --git a/dhall_core/src/core.rs b/dhall_core/src/core.rs
index a9033f3..355f625 100644
--- a/dhall_core/src/core.rs
+++ b/dhall_core/src/core.rs
@@ -12,6 +12,13 @@ pub type Double = NaiveDouble;
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum X {}
+pub fn trivial_result<T>(x: Result<T, X>) -> T {
+ match x {
+ Ok(x) => x,
+ Err(e) => match e {},
+ }
+}
+
/// Double with bitwise equality
#[derive(Debug, Copy, Clone)]
pub struct NaiveDouble(f64);
@@ -362,83 +369,122 @@ impl<SE, L, N, E> ExprF<SE, L, N, E> {
}
#[inline(always)]
- pub fn map<SE2, L2, N2, E2, F1, F2, F3, F4, F5>(
+ pub fn traverse<SE2, L2, N2, E2, Err, F1, F2, F3, F4, F5>(
self,
map_subexpr: F1,
map_under_binder: F2,
map_note: F3,
map_embed: F4,
mut map_label: F5,
- ) -> ExprF<SE2, L2, N2, E2>
+ ) -> Result<ExprF<SE2, L2, N2, E2>, Err>
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(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>,
{
let mut map = map_subexpr;
- fn vec<T, U, F: FnMut(T) -> U>(x: Vec<T>, f: F) -> Vec<U> {
+ fn vec<T, U, Err, F: FnMut(T) -> Result<U, Err>>(
+ x: Vec<T>,
+ f: F,
+ ) -> Result<Vec<U>, Err> {
x.into_iter().map(f).collect()
}
- fn btmap<K, L, T, U, FK, FV>(
+ fn opt<T, U, Err, F: FnOnce(T) -> Result<U, Err>>(
+ x: Option<T>,
+ f: F,
+ ) -> Result<Option<U>, Err> {
+ Ok(match x {
+ Some(x) => Some(f(x)?),
+ None => None,
+ })
+ }
+ fn btmap<K, L, T, U, Err, FK, FV>(
x: BTreeMap<K, T>,
mut fk: FK,
mut fv: FV,
- ) -> BTreeMap<L, U>
+ ) -> Result<BTreeMap<L, U>, Err>
where
K: Ord,
L: Ord,
- FK: FnMut(K) -> L,
- FV: FnMut(T) -> U,
+ FK: FnMut(K) -> Result<L, Err>,
+ FV: FnMut(T) -> Result<U, Err>,
{
- x.into_iter().map(|(k, v)| (fk(k), fv(v))).collect()
+ x.into_iter().map(|(k, v)| Ok((fk(k)?, fv(v)?))).collect()
}
use crate::ExprF::*;
- match self {
- Var(V(l, n)) => Var(V(map_label(l), n)),
+ Ok(match self {
+ 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)
+ let b = map_under_binder(&l, b)?;
+ Lam(map_label(l)?, map(t)?, b)
}
Pi(l, t, b) => {
- let b = map_under_binder(&l, b);
- Pi(map_label(l), map(t), b)
+ let b = map_under_binder(&l, b)?;
+ Pi(map_label(l)?, map(t)?, b)
}
Let(l, t, a, b) => {
- let b = map_under_binder(&l, b);
- Let(map_label(l), t.map(&mut map), map(a), b)
+ let b = map_under_binder(&l, b)?;
+ Let(map_label(l)?, opt(t, &mut map)?, map(a)?, b)
}
- App(f, args) => App(map(f), vec(args, map)),
- Annot(x, t) => Annot(map(x), map(t)),
+ 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.map(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)),
- EmptyOptionalLit(t) => EmptyOptionalLit(map(t)),
- NEOptionalLit(e) => NEOptionalLit(map(e)),
- RecordType(kts) => RecordType(btmap(kts, map_label, map)),
- RecordLit(kvs) => RecordLit(btmap(kvs, map_label, map)),
- UnionType(kts) => UnionType(btmap(kts, map_label, map)),
+ TextLit(t) => TextLit(t.traverse(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)?),
+ EmptyOptionalLit(t) => EmptyOptionalLit(map(t)?),
+ NEOptionalLit(e) => NEOptionalLit(map(e)?),
+ RecordType(kts) => RecordType(btmap(kts, map_label, map)?),
+ RecordLit(kvs) => RecordLit(btmap(kvs, map_label, map)?),
+ UnionType(kts) => UnionType(btmap(kts, map_label, map)?),
UnionLit(k, v, kvs) => {
- UnionLit(map_label(k), map(v), btmap(kvs, map_label, map))
+ UnionLit(map_label(k)?, map(v)?, btmap(kvs, map_label, map)?)
}
- Merge(x, y, t) => Merge(map(x), map(y), t.map(map)),
- Field(e, l) => Field(map(e), map_label(l)),
- Projection(e, ls) => Projection(map(e), vec(ls, map_label)),
- Note(n, e) => Note(map_note(n), map(e)),
- Embed(a) => Embed(map_embed(a)),
- }
+ Merge(x, y, t) => Merge(map(x)?, map(y)?, opt(t, map)?),
+ Field(e, l) => Field(map(e)?, map_label(l)?),
+ Projection(e, ls) => Projection(map(e)?, vec(ls, map_label)?),
+ Note(n, e) => Note(map_note(n)?, map(e)?),
+ Embed(a) => Embed(map_embed(a)?),
+ })
+ }
+
+ #[inline(always)]
+ pub fn map<SE2, L2, N2, E2, F1, F2, F3, F4, F5>(
+ self,
+ mut map_subexpr: F1,
+ map_under_binder: F2,
+ map_note: F3,
+ map_embed: F4,
+ mut map_label: F5,
+ ) -> ExprF<SE2, L2, N2, E2>
+ 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,
+ {
+ trivial_result(self.traverse(
+ |x| Ok(map_subexpr(x)),
+ |l, x| Ok(map_under_binder(l, x)),
+ |x| Ok(map_note(x)),
+ |x| Ok(map_embed(x)),
+ |x| Ok(map_label(x)),
+ ))
}
#[inline(always)]
diff --git a/dhall_core/src/text.rs b/dhall_core/src/text.rs
index 9500f32..7c0e2b4 100644
--- a/dhall_core/src/text.rs
+++ b/dhall_core/src/text.rs
@@ -34,18 +34,28 @@ pub enum InterpolatedTextContents<SubExpr> {
}
impl<SubExpr> InterpolatedText<SubExpr> {
- pub fn map<SubExpr2, F>(self, mut f: F) -> InterpolatedText<SubExpr2>
+ pub fn traverse<SubExpr2, E, F>(
+ self,
+ mut f: F,
+ ) -> Result<InterpolatedText<SubExpr2>, E>
where
- F: FnMut(SubExpr) -> SubExpr2,
+ F: FnMut(SubExpr) -> Result<SubExpr2, E>,
{
- InterpolatedText {
+ Ok(InterpolatedText {
head: self.head.clone(),
tail: self
.tail
.into_iter()
- .map(|(e, s)| (f(e), s.clone()))
- .collect(),
- }
+ .map(|(e, s)| Ok((f(e)?, s.clone())))
+ .collect::<Result<_, _>>()?,
+ })
+ }
+
+ pub fn map<SubExpr2, F>(self, mut f: F) -> InterpolatedText<SubExpr2>
+ where
+ F: FnMut(SubExpr) -> SubExpr2,
+ {
+ crate::trivial_result(self.traverse(|e| Ok(f(e))))
}
pub fn as_ref(&self) -> InterpolatedText<&SubExpr> {