module Data.TreeMap.Strict.Zipper where
import Control.Monad (Monad(..), (>=>))
import Control.Applicative (Applicative(..), Alternative(..))
import Data.Bool (Bool)
import Data.Data (Data)
import Data.Eq (Eq)
import Data.Function (($), (.))
import Data.Functor ((<$>))
import Data.Int (Int)
import qualified Data.List as List
import Data.List.NonEmpty (NonEmpty(..))
import qualified Data.Map.Strict as Map
import Data.Maybe (Maybe(..), maybe, maybeToList)
import Data.Ord (Ord(..))
import Data.Tuple (fst)
import Data.Typeable (Typeable)
import Text.Show (Show(..))
import Data.TreeMap.Strict (TreeMap(..))
import qualified Data.TreeMap.Strict as TreeMap
data Zipper k a
= Zipper
{ zipper_path :: [Zipper_Step k a]
, zipper_curr :: TreeMap k a
} deriving (Data, Eq, Show, Typeable)
zipper :: TreeMap k a -> Zipper k a
zipper = Zipper []
zipper_root :: Ord k => Zipper k a -> TreeMap k a
zipper_root = zipper_curr . List.last . zipper_ancestor_or_self
path_of_zipper :: Zipper k x -> [k]
path_of_zipper z =
fst . zipper_step_self <$>
List.reverse (zipper_path z)
data Zipper_Step k a
= Zipper_Step
{ zipper_step_prec :: TreeMap k a
, zipper_step_self :: (k, TreeMap.Node k a)
, zipper_step_foll :: TreeMap k a
} deriving (Data, Eq, Show, Typeable)
zipper_collect :: (z -> Maybe z) -> z -> [z]
zipper_collect f z = z : maybe [] (zipper_collect f) (f z)
zipper_collect_without_self :: (z -> Maybe z) -> z -> [z]
zipper_collect_without_self f z = maybe [] (zipper_collect f) (f z)
zipper_self :: Zipper k a -> TreeMap.Node k a
zipper_self z =
case z of
Zipper{ zipper_path=
Zipper_Step{zipper_step_self=(_, nod)}
: _ } -> nod
_ -> TreeMap.node_empty
zipper_child :: Ord k => Zipper k a -> [Zipper k a]
zipper_child z =
maybeToList (zipper_child_first z)
>>= zipper_collect zipper_foll
zipper_child_lookup
:: (Ord k, Alternative f)
=> k -> Zipper k a -> f (Zipper k a)
zipper_child_lookup k (Zipper path (TreeMap m)) =
case Map.splitLookup k m of
(_, Nothing, _) -> empty
(ps, Just s, fs) ->
pure Zipper
{ zipper_path = Zipper_Step (TreeMap ps) (k, s) (TreeMap fs) : path
, zipper_curr = TreeMap.node_descendants s
}
zipper_child_first :: Alternative f => Zipper k a -> f (Zipper k a)
zipper_child_first (Zipper path (TreeMap m)) =
case Map.minViewWithKey m of
Nothing -> empty
Just ((k', s'), fs') ->
pure Zipper
{ zipper_path = Zipper_Step TreeMap.empty (k', s') (TreeMap fs') : path
, zipper_curr = TreeMap.node_descendants s'
}
zipper_child_last :: Alternative f => Zipper k a -> f (Zipper k a)
zipper_child_last (Zipper path (TreeMap m)) =
case Map.maxViewWithKey m of
Nothing -> empty
Just ((k', s'), ps') ->
pure Zipper
{ zipper_path = Zipper_Step (TreeMap ps') (k', s') TreeMap.empty : path
, zipper_curr = TreeMap.node_descendants s'
}
zipper_ancestor :: Ord k => Zipper k a -> [Zipper k a]
zipper_ancestor = zipper_collect_without_self zipper_parent
zipper_ancestor_or_self :: Ord k => Zipper k a -> [Zipper k a]
zipper_ancestor_or_self = zipper_collect zipper_parent
zipper_descendant_or_self :: Ord k => Zipper k a -> [Zipper k a]
zipper_descendant_or_self =
collect_child []
where
collect_child acc z =
z : maybe acc
(collect_foll acc)
(zipper_child_first z)
collect_foll acc z =
collect_child
(maybe acc
(collect_foll acc)
(zipper_foll z)
) z
zipper_descendant_or_self_reverse :: Ord k => Zipper k a -> [Zipper k a]
zipper_descendant_or_self_reverse z =
z : List.concatMap
zipper_descendant_or_self_reverse
(List.reverse $ zipper_child z)
zipper_descendant :: Ord k => Zipper k a -> [Zipper k a]
zipper_descendant = List.tail . zipper_descendant_or_self
zipper_descendant_lookup
:: (Ord k, Alternative f, Monad f)
=> TreeMap.Path k -> Zipper k a -> f (Zipper k a)
zipper_descendant_lookup (k:|ks) =
case ks of
[] -> zipper_child_lookup k
k':ks' -> zipper_child_lookup k >=> zipper_descendant_lookup (k':|ks')
zipper_prec :: (Ord k, Alternative f) => Zipper k a -> f (Zipper k a)
zipper_prec (Zipper path _curr) =
case path of
[] -> empty
Zipper_Step (TreeMap ps) (k, s) (TreeMap fs):steps ->
case Map.maxViewWithKey ps of
Nothing -> empty
Just ((k', s'), ps') ->
pure Zipper
{ zipper_path = Zipper_Step (TreeMap ps')
(k', s')
(TreeMap $ Map.insert k s fs)
: steps
, zipper_curr = TreeMap.node_descendants s'
}
zipper_preceding :: Ord k => Zipper k a -> [Zipper k a]
zipper_preceding =
zipper_ancestor_or_self >=>
zipper_preceding_sibling >=>
zipper_descendant_or_self_reverse
zipper_preceding_sibling :: Ord k => Zipper k a -> [Zipper k a]
zipper_preceding_sibling = zipper_collect_without_self zipper_prec
zipper_foll :: (Ord k, Alternative f) => Zipper k a -> f (Zipper k a)
zipper_foll (Zipper path _curr) =
case path of
[] -> empty
Zipper_Step (TreeMap ps) (k, s) (TreeMap fs):steps ->
case Map.minViewWithKey fs of
Nothing -> empty
Just ((k', s'), fs') ->
pure Zipper
{ zipper_path = Zipper_Step (TreeMap $ Map.insert k s ps)
(k', s')
(TreeMap fs')
: steps
, zipper_curr = TreeMap.node_descendants s'
}
zipper_following :: Ord k => Zipper k a -> [Zipper k a]
zipper_following =
zipper_ancestor_or_self >=>
zipper_following_sibling >=>
zipper_descendant_or_self
zipper_following_sibling :: Ord k => Zipper k a -> [Zipper k a]
zipper_following_sibling = zipper_collect_without_self zipper_foll
zipper_parent :: (Ord k, Alternative f) => Zipper k a -> f (Zipper k a)
zipper_parent (Zipper path curr) =
case path of
[] -> empty
Zipper_Step (TreeMap ps) (k, s) (TreeMap fs):steps ->
let nod = TreeMap.node (TreeMap.node_value s) curr in
pure Zipper
{ zipper_path = steps
, zipper_curr = TreeMap $ Map.union ps $ Map.insert k nod fs
}
zipper_filter
:: (Zipper k a -> [Zipper k a])
-> (Zipper k a -> Bool)
-> (Zipper k a -> [Zipper k a])
zipper_filter axis p z = List.filter p (axis z)
infixl 5 `zipper_filter`
zipper_at :: Alternative f
=> (Zipper k a -> [Zipper k a]) -> Int
-> (Zipper k a -> f (Zipper k a))
zipper_at axis n z = case List.drop n (axis z) of {[] -> empty; a:_ -> pure a}
infixl 5 `zipper_at`
zipper_null
:: (Zipper k a -> [Zipper k a])
-> Zipper k a -> Bool
zipper_null axis = List.null . axis