summaryrefslogtreecommitdiff
path: root/dhall/src
diff options
context:
space:
mode:
authorNadrieril2019-03-23 23:24:11 +0100
committerNadrieril2019-03-23 23:24:11 +0100
commit062fc44a93a18ee432e51db852290ab5849f4dd9 (patch)
treec9dd53daf9cd99f5dcf982e1d98099a078f63110 /dhall/src
parentf610bc0aac5eaa365c95b489fb2d06cab449ec77 (diff)
Handle merge and record projection
Diffstat (limited to 'dhall/src')
-rw-r--r--dhall/src/normalize.rs41
1 files changed, 36 insertions, 5 deletions
diff --git a/dhall/src/normalize.rs b/dhall/src/normalize.rs
index 4652b25..2ffa5a5 100644
--- a/dhall/src/normalize.rs
+++ b/dhall/src/normalize.rs
@@ -276,14 +276,45 @@ where
(o, _, _) => BinOp(*o, x, y),
})
}
- Field(e, x) => {
+ Merge(x, y, t) => {
+ let x = normalize_whnf(x);
+ let y = normalize_whnf(y);
+ match (x.as_ref(), y.as_ref()) {
+ (RecordLit(handlers), UnionLit(k, v, _)) => {
+ match handlers.get(&k) {
+ Some(h) => {
+ normalize_whnf(&rc(App(h.clone(), vec![v.clone()])))
+ }
+ None => rc(Merge(x, y, t.clone())),
+ }
+ }
+ _ => rc(Merge(x, y, t.clone())),
+ }
+ }
+ Field(e, l) => {
let e = normalize_whnf(e);
- match (e.as_ref(), x) {
- (RecordLit(kvs), x) => match kvs.get(&x) {
+ match e.as_ref() {
+ RecordLit(kvs) => match kvs.get(&l) {
Some(r) => normalize_whnf(r),
- None => rc(Field(e, x.clone())),
+ None => rc(Field(e, l.clone())),
},
- (_, x) => rc(Field(e, x.clone())),
+ _ => rc(Field(e, l.clone())),
+ }
+ }
+ Projection(_, ls) if ls.is_empty() => {
+ rc(RecordLit(std::collections::BTreeMap::new()))
+ }
+ Projection(e, ls) => {
+ let e = normalize_whnf(e);
+ match e.as_ref() {
+ RecordLit(kvs) => rc(RecordLit(
+ ls.iter()
+ .filter_map(|l| {
+ kvs.get(l).map(|x| (l.clone(), x.clone()))
+ })
+ .collect(),
+ )),
+ _ => rc(Projection(e, ls.clone())),
}
}
_ => Rc::clone(e),