1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
use crate::syntax::core::{Closure, Elim, Term, Val}; pub trait FoldVal { fn try_fold_val<E, R>( &self, init: R, f: impl Fn(R, &Val) -> Result<R, E> + Copy, ) -> Result<R, E>; } impl<T: FoldVal> FoldVal for [T] { fn try_fold_val<E, R>( &self, init: R, f: impl Fn(R, &Val) -> Result<R, E> + Copy, ) -> Result<R, E> { self.iter().try_fold(init, |a, v| v.try_fold_val(a, f)) } } impl FoldVal for Term { fn try_fold_val<E, R>( &self, init: R, f: impl Fn(R, &Val) -> Result<R, E> + Copy, ) -> Result<R, E> { use Term::*; match self { Whnf(val) => val.try_fold_val(init, f), Redex(_, args) => args.try_fold_val(init, f), } } } impl FoldVal for Elim { fn try_fold_val<E, R>( &self, init: R, f: impl Fn(R, &Val) -> Result<R, E> + Copy, ) -> Result<R, E> { match self { Elim::App(a) => a.try_fold_val(init, f), Elim::Proj(..) => Ok(init), } } } impl FoldVal for Closure { fn try_fold_val<E, R>( &self, init: R, f: impl Fn(R, &Val) -> Result<R, E> + Copy, ) -> Result<R, E> { match self { Closure::Plain(t) => t.try_fold_val(init, f), } } } impl FoldVal for Val { fn try_fold_val<E, R>( &self, init: R, f: impl Fn(R, &Val) -> Result<R, E> + Copy, ) -> Result<R, E> { use Val::*; let init = f(init, self)?; match self { Data(_, _, v) | Cons(_, v) => v.try_fold_val(init, f), Axiom(..) | Type(..) | Refl => Ok(init), Pi(p, clos) => clos.try_fold_val(p.ty.try_fold_val(init, f)?, f), Id(a, b, c) => c.try_fold_val(b.try_fold_val(a.try_fold_val(init, f)?, f)?, f), Var(_, v) | Meta(_, v) => v.try_fold_val(init, f), } } }