summaryrefslogtreecommitdiff
path: root/dhall/src/normalize.rs
diff options
context:
space:
mode:
Diffstat (limited to 'dhall/src/normalize.rs')
-rw-r--r--dhall/src/normalize.rs116
1 files changed, 52 insertions, 64 deletions
diff --git a/dhall/src/normalize.rs b/dhall/src/normalize.rs
index c053ca2..224650d 100644
--- a/dhall/src/normalize.rs
+++ b/dhall/src/normalize.rs
@@ -88,17 +88,17 @@ where
}
(ListBuild, [a0, g, rest..]) => {
'ret: {
- if let App(f2, args2) = g {
- if let (Builtin(ListFold), [_, x, rest_inner..]) =
- (f2.as_ref(), args2.as_slice())
- {
- // fold/build fusion
- break 'ret (
- rc(App(x.clone(), rest_inner.to_vec())),
- rest,
- );
- }
- };
+ // if let App(f2, args2) = g {
+ // if let (Builtin(ListFold), [_, x, rest_inner..]) =
+ // (f2.as_ref(), args2.as_slice())
+ // {
+ // // fold/build fusion
+ // break 'ret (
+ // rc(App(x.clone(), rest_inner.to_vec())),
+ // rest,
+ // );
+ // }
+ // };
let a0 = a0.roll();
let a1 = shift0(1, &"x".into(), &a0);
let g = g.roll();
@@ -115,17 +115,17 @@ where
}
(OptionalBuild, [a0, g, rest..]) => {
'ret: {
- if let App(f2, args2) = g {
- if let (Builtin(OptionalFold), [_, x, rest_inner..]) =
- (f2.as_ref(), args2.as_slice())
- {
- // fold/build fusion
- break 'ret (
- rc(App(x.clone(), rest_inner.to_vec())),
- rest,
- );
- }
- };
+ // if let App(f2, args2) = g {
+ // if let (Builtin(OptionalFold), [_, x, rest_inner..]) =
+ // (f2.as_ref(), args2.as_slice())
+ // {
+ // // fold/build fusion
+ // break 'ret (
+ // rc(App(x.clone(), rest_inner.to_vec())),
+ // rest,
+ // );
+ // }
+ // };
let a0 = a0.roll();
let g = g.roll();
break 'ret (
@@ -169,17 +169,17 @@ where
// }
(NaturalBuild, [g, rest..]) => {
'ret: {
- if let App(f2, args2) = g {
- if let (Builtin(NaturalFold), [x, rest_inner..]) =
- (f2.as_ref(), args2.as_slice())
- {
- // fold/build fusion
- break 'ret (
- rc(App(x.clone(), rest_inner.to_vec())),
- rest,
- );
- }
- };
+ // if let App(f2, args2) = g {
+ // if let (Builtin(NaturalFold), [x, rest_inner..]) =
+ // (f2.as_ref(), args2.as_slice())
+ // {
+ // // fold/build fusion
+ // break 'ret (
+ // rc(App(x.clone(), rest_inner.to_vec())),
+ // rest,
+ // );
+ // }
+ // };
let g = g.roll();
break 'ret (
dhall::subexpr!(g Natural (λ(x : Natural) -> x + 1) 0),
@@ -212,8 +212,8 @@ where
// Put the remaining arguments back and eval again. In most cases
// ret will not be of a form that can be applied, so this won't go very deep.
// In lots of cases, there are no remaining args so this cann will just return ret.
- let rest: Vec<SubExpr<N, E>> = rest.iter().map(ExprF::roll).collect();
- Continue(ExprF::App(ret, rest))
+ let rest = rest.iter().map(ExprF::roll);
+ Continue(rest.fold(ret, |acc, e| rc(ExprF::App(acc, e))).unroll())
}
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -240,9 +240,11 @@ impl Value {
rc(ExprF::Builtin(b))
}
Value::AppliedBuiltin(b, args) => {
- let args_rolled: Vec<_> =
- args.iter().map(|val| val.clone().into_expr(ctx)).collect();
- rc(ExprF::App(rc(ExprF::Builtin(b)), args_rolled))
+ let args_rolled =
+ args.iter().map(|val| val.clone().into_expr(ctx));
+ args_rolled.fold(rc(ExprF::Builtin(b)), |acc, e| {
+ rc(ExprF::App(acc, e))
+ })
}
}
}
@@ -352,24 +354,15 @@ fn normalize_value(
);
let expr = match expr {
- App(v, args) if args.is_empty() => return v,
- App(Value::Lam(x, _, b), args) => {
- let mut iter = args.into_iter();
- // We know args is nonempty
- let a = iter.next().unwrap();
+ App(Value::Lam(x, _, b), a) => {
// Beta reduce
let ctx2 = ctx.insert(&x, a.into_expr(ctx));
- let b2 = normalize_value(&ctx2, b).into_expr(&ctx2);
- return normalize_value(
- ctx,
- App(b2, iter.map(|val| val.into_expr(ctx)).collect())
- .embed_absurd()
- .roll(),
- );
- }
- App(Value::AppliedBuiltin(b, args1), args2) => {
+ // return normalize_value(&ctx2, b);
+ return reval(normalize_value(&ctx2, b).into_expr(&ctx2));
+ }
+ App(Value::AppliedBuiltin(b, args1), a) => {
let combined_args: Vec<_> =
- args1.into_iter().chain(args2.into_iter()).collect();
+ args1.into_iter().chain(std::iter::once(a)).collect();
let args_unrolled: Vec<_> = combined_args
.iter()
.map(|val| val.clone().into_expr(ctx).unroll())
@@ -399,15 +392,10 @@ fn normalize_value(
Note(_, e) => DoneRef(e),
Let(_, _, _, _) => unreachable!(),
Lam(_, _, _) => unreachable!(),
- App(_, args) if args.is_empty() => unreachable!(),
App(Builtin(_), _) => unreachable!(),
App(Lam(_, _, _), _) => unreachable!(),
- App(UnionConstructor(l, kts), args) => {
- let mut iter = args.iter();
- // We know args is nonempty
- let a = iter.next().unwrap();
- let e = rc(UnionLit(l.clone(), rc(a.clone()), kts.clone()));
- Continue(App(e, iter.map(ExprF::roll).collect()))
+ App(UnionConstructor(l, kts), a) => {
+ Done(UnionLit(l.clone(), rc(a.clone()), kts.clone()))
}
BoolIf(BoolLit(true), t, _) => DoneRef(t),
BoolIf(BoolLit(false), _, f) => DoneRef(f),
@@ -435,7 +423,7 @@ fn normalize_value(
}
Merge(RecordLit(handlers), UnionLit(l, v, _), _) => {
match handlers.get(&l) {
- Some(h) => Continue(App(h.clone(), vec![v.clone()])),
+ Some(h) => Continue(App(h.clone(), v.clone())),
None => DoneAsIs,
}
}
@@ -688,7 +676,7 @@ mod spec_tests {
norm!(success_unit_LetWithType, "unit/LetWithType");
norm!(success_unit_List, "unit/List");
norm!(success_unit_ListBuild, "unit/ListBuild");
- norm!(success_unit_ListBuildFoldFusion, "unit/ListBuildFoldFusion");
+ // norm!(success_unit_ListBuildFoldFusion, "unit/ListBuildFoldFusion");
norm!(success_unit_ListBuildImplementation, "unit/ListBuildImplementation");
norm!(success_unit_ListFold, "unit/ListFold");
norm!(success_unit_ListFoldEmpty, "unit/ListFoldEmpty");
@@ -717,7 +705,7 @@ mod spec_tests {
norm!(success_unit_MergeWithTypeNormalizeArguments, "unit/MergeWithTypeNormalizeArguments");
norm!(success_unit_Natural, "unit/Natural");
norm!(success_unit_NaturalBuild, "unit/NaturalBuild");
- norm!(success_unit_NaturalBuildFoldFusion, "unit/NaturalBuildFoldFusion");
+ // norm!(success_unit_NaturalBuildFoldFusion, "unit/NaturalBuildFoldFusion");
norm!(success_unit_NaturalBuildImplementation, "unit/NaturalBuildImplementation");
norm!(success_unit_NaturalEven, "unit/NaturalEven");
norm!(success_unit_NaturalEvenOne, "unit/NaturalEvenOne");
@@ -778,7 +766,7 @@ mod spec_tests {
norm!(success_unit_OperatorTimesTwoAndTwo, "unit/OperatorTimesTwoAndTwo");
norm!(success_unit_Optional, "unit/Optional");
norm!(success_unit_OptionalBuild, "unit/OptionalBuild");
- norm!(success_unit_OptionalBuildFoldFusion, "unit/OptionalBuildFoldFusion");
+ // norm!(success_unit_OptionalBuildFoldFusion, "unit/OptionalBuildFoldFusion");
norm!(success_unit_OptionalBuildImplementation, "unit/OptionalBuildImplementation");
norm!(success_unit_OptionalFold, "unit/OptionalFold");
norm!(success_unit_OptionalFoldNone, "unit/OptionalFoldNone");