+ case App nt nu of
+ l@(RedEx _ _ _) -> traversPost f =<< f l
+ r -> return r
+traversPost f (Lambda x t) = return . Lambda x =<< traversPost f t
+traversPost f (Var x) = return $ (Var x)
+
+data Z = R Term Z | L Z Term | ZL VarName Z | E
+data D = Up | Down
+data Zip = Zip Z Term
+
+move (App l r, c, Down) = (l, L c r, Down)
+move (Lambda x t, c, Down) = (t, ZL x c, Down)
+move (Var x, c, Down) = (Var x, c, Up)
+move (t, L c r, Up) = (r, R t c, Down)
+move (t, R l c, Up) = (App l t, c, Up)
+move (t, ZL x c, Up) = (Lambda x t, c, Up)
+move (t, E, Up) = (t, E, Up)
+
+unmove (t, L c r, Down) = (App t r, c, Down)
+unmove x = x
+
+getF (t, _, _) = t
+
+travPost :: (Monad m) => (Term -> m Term) -> Term -> m Term
+travPost fnc term = tr fnc (term, E, Down)
+ where
+ tr f (t@(RedEx _ _ _), c, Up) = do
+ nt <- f t
+ tr f $ (nt, c, Down)
+ tr f (t, E, Up) = return t
+ tr f (t, c, Up) = tr f $ move (t, c, Up)
+ tr f (t, c, Down) = tr f $ move (t, c, Down)
+
+travPre :: (Monad m) => (Term -> m Term) -> Term -> m Term
+travPre fnc term = tr fnc (term, E, Down)
+ where
+ tr f (t@(RedEx _ _ _), c, Down) = do
+ nt <- f t
+ tr f $ unmove (nt, c, Down)
+ tr f (t, E, Up) = return t
+ tr f (t, c, Up) = tr f $ move (t, c, Up)
+ tr f (t, c, Down) = tr f $ move (t, c, Down)