module Data.Cursor.CLASE.Traversal(
Traversal(..),
completeTraversal
) where
import Data.Cursor.CLASE.Bound
import Data.Cursor.CLASE.Language
class (Bound l t) => Traversal l t where
visitStep :: (Reify l a) => a -> (forall b . Reify l b => Movement l Down a b -> t) -> t
visitPartial :: Context l a b -> b -> t -> (forall c . Reify l c => Movement l Down b c -> t) -> t
cursor :: l -> t -> t
completeTraversal :: forall l t x a . (Traversal l t) => Cursor l x a -> t
completeTraversal (Cursor it ctx _) = foldUp (cursor (undefined :: l) (visitStep it hook')) it ctx
where
hook' :: forall b . Reify l b => Movement l Down a b -> t
hook' = hook it
hook :: forall l t a b . (Traversal l t, Reify l b) => a -> Movement l Down a b -> t
hook here movement = case unbuildOne movement here of
Just (ctx, b) -> let hook' :: forall c . Reify l c => Movement l Down b c -> t
hook' = hook b
in bindingHook ctx (visitStep b hook')
Nothing -> error "Bad movement in traversal!"
foldUp :: (Traversal l t) => t -> a -> Path l (Context l) a b -> t
foldUp t _ Stop = t
foldUp t here (Step ctx nxt) = foldUp (bindingHook ctx (visitPartial ctx next t (hook next))) next nxt
where
next = buildOne ctx here