data Ord k
=> Node k x
= Node
- { node_size :: Int -- ^ The number of non-'Nothing' 'node_content's reachable from this 'Node'.
- , node_content :: Maybe x -- ^ Some content, or 'Nothing' if this 'Node' is intermediary.
+ { node_size :: Int -- ^ The number of non-'Nothing' 'node_value's reachable from this 'Node'.
+ , node_value :: Maybe x -- ^ Some value, or 'Nothing' if this 'Node' is intermediary.
, node_descendants :: TreeMap k x -- ^ Descendants 'Node's.
} deriving (Data, Eq, Read, Show, Typeable)
instance (Ord k, Monoid v) => Monoid (Node k v) where
mempty =
Node
- { node_content = Nothing
+ { node_value = Nothing
, node_size = 0
, node_descendants = TreeMap mempty
}
mappend
- Node{node_content=x0, node_descendants=m0}
- Node{node_content=x1, node_descendants=m1} =
+ Node{node_value=x0, node_descendants=m0}
+ Node{node_value=x1, node_descendants=m1} =
let m = union const m0 m1 in
let x = x0 `mappend` x1 in
Node
- { node_content = x
+ { node_value = x
, node_size = size m + maybe 0 (const 1) x
, node_descendants = union const m0 m1
}
-- mconcat = Data.List.foldr mappend mempty
instance Ord k => Functor (Node k) where
- fmap f Node{node_content=x, node_descendants=m, node_size} =
+ fmap f Node{node_value=x, node_descendants=m, node_size} =
Node
- { node_content = fmap f x
+ { node_value = fmap f x
, node_descendants = Hcompta.Lib.TreeMap.map f m
, node_size
}
instance Ord k => Foldable (Node k) where
- foldMap f Node{node_content=Nothing, node_descendants=TreeMap m} =
+ foldMap f Node{node_value=Nothing, node_descendants=TreeMap m} =
foldMap (foldMap f) m
- foldMap f Node{node_content=Just x, node_descendants=TreeMap m} =
+ foldMap f Node{node_value=Just x, node_descendants=TreeMap m} =
f x `mappend` foldMap (foldMap f) m
instance Ord k => Traversable (Node k) where
- traverse f Node{node_content=Nothing, node_descendants=TreeMap m, node_size} =
+ traverse f Node{node_value=Nothing, node_descendants=TreeMap m, node_size} =
Node node_size <$> pure Nothing <*> (TreeMap <$> traverse (traverse f) m)
- traverse f Node{node_content=Just x, node_descendants=TreeMap m, node_size} =
+ traverse f Node{node_value=Just x, node_descendants=TreeMap m, node_size} =
Node node_size <$> (Just <$> f x) <*> (TreeMap <$> traverse (traverse f) m)
-- * Contructors
leaf :: Ord k => x -> Node k x
leaf x =
Node
- { node_content = Just x
+ { node_value = Just x
, node_descendants = empty
- , node_size = 1
+ , node_size = 1
}
--- | Return the given 'TreeMap' associating the given 'Path' with the given content,
--- merging contents if the given 'TreeMap' already associates the given 'Path'
--- with a non-'Nothing' 'node_content'.
+-- | Return the given 'TreeMap' associating the given 'Path' with the given value,
+-- merging values if the given 'TreeMap' already associates the given 'Path'
+-- with a non-'Nothing' 'node_value'.
insert :: Ord k => (x -> x -> x) -> Path k -> x -> TreeMap k x -> TreeMap k x
insert merge (k:|[]) x (TreeMap m) =
TreeMap $
Data.Map.insertWith
- (\_ Node{node_content=x1, node_descendants=m1, node_size=s1} ->
+ (\_ Node{node_value=x1, node_descendants=m1, node_size=s1} ->
Node
- { node_content = maybe (Just x) (Just . merge x) x1
+ { node_value = maybe (Just x) (Just . merge x) x1
, node_descendants = m1
, node_size = maybe (s1 + 1) (const s1) x1
})
insert merge (k:|k':ks) x (TreeMap m) =
TreeMap $
Data.Map.insertWith
- (\_ Node{node_content=x1, node_descendants=m1} ->
+ (\_ Node{node_value=x1, node_descendants=m1} ->
let m' = insert merge (path k' ks) x m1 in
- Node{node_content=x1, node_descendants=m', node_size=size m' + maybe 0 (const 1) x1})
+ Node{node_value=x1, node_descendants=m', node_size=size m' + maybe 0 (const 1) x1})
k
(Node
- { node_content = Nothing
+ { node_value = Nothing
, node_descendants = insert merge (path k' ks) x empty
, node_size = 1
})
m
--- | Return a 'TreeMap' associating the given 'Path' to the given content,
--- merging content of identical 'Path's (in respective order).
+-- | Return a 'TreeMap' associating for each tuple of the given list
+-- the 'Path' to the value,
+-- merging values of identical 'Path's (in respective order).
from_List :: Ord k => (x -> x -> x) -> [(Path k, x)] -> TreeMap k x
from_List merge = Data.List.foldl (\acc (p, x) -> insert merge p x acc) empty
+-- | Return a 'TreeMap' associating for each key and value of the given 'Data.Map.Map'
+-- the 'Path' to the value,
+-- merging values of identical 'Path's (in respective order).
+from_Map :: Ord k => (x -> x -> x) -> Data.Map.Map (Path k) x -> TreeMap k x
+from_Map merge = Data.Map.foldlWithKey (\acc p x -> insert merge p x acc) empty
+
-- | Return a 'TreeMap' associating the same 'Path's as both given 'TreeMap's,
--- merging contents (in respective order) when a 'Path' leads
--- to a non-'Nothing' 'node_content' in both given 'TreeMap's.
+-- merging values (in respective order) when a 'Path' leads
+-- to a non-'Nothing' 'node_value' in both given 'TreeMap's.
union :: Ord k => (x -> x -> x) -> TreeMap k x -> TreeMap k x -> TreeMap k x
union merge (TreeMap tm0) (TreeMap tm1) =
TreeMap $
Data.Map.unionWith
- (\Node{node_content=x0, node_descendants=m0}
- Node{node_content=x1, node_descendants=m1} ->
+ (\Node{node_value=x0, node_descendants=m0}
+ Node{node_value=x1, node_descendants=m1} ->
let m = union merge m0 m1 in
let x = maybe x1 (\x0' -> maybe (Just x0') (Just . merge x0') x1) x0 in
Node
- { node_content = x
+ { node_value = x
, node_descendants = m
, node_size = size m + maybe 0 (const 1) x
})
-- go z [] = z
-- go z (x:xs) = z `seq` go (f z x) xs
--- | Return the given 'TreeMap' with each non-'Nothing' 'node_content'
+-- | Return the given 'TreeMap' with each non-'Nothing' 'node_value'
-- mapped by the given function.
map :: Ord k => (x -> y) -> TreeMap k x -> TreeMap k y
map f =
TreeMap .
Data.Map.map
- (\n@Node{node_content=x, node_descendants=m} ->
- n{ node_content=maybe Nothing (Just . f) x
+ (\n@Node{node_value=x, node_descendants=m} ->
+ n{ node_value=maybe Nothing (Just . f) x
, node_descendants=Hcompta.Lib.TreeMap.map f m
}) .
nodes
--- | Return the given 'TreeMap' with each 'node_content'
+-- | Return the given 'TreeMap' with each 'node_value'
-- mapped by the given function supplied with
-- the already mapped 'node_descendants' of the current 'Node'.
map_by_depth_first :: Ord k => (TreeMap k y -> Maybe x -> y) -> TreeMap k x -> TreeMap k y
map_by_depth_first f =
TreeMap .
Data.Map.map
- (\n@Node{node_content, node_descendants} ->
+ (\n@Node{node_value, node_descendants} ->
let m = map_by_depth_first f node_descendants in
- let x = f m node_content in
- n{ node_content = Just x
+ let x = f m node_value in
+ n{ node_value = Just x
, node_descendants = m
, node_size = size m + 1
}) .
nodes :: TreeMap k x -> Data.Map.Map k (Node k x)
nodes (TreeMap m) = m
--- | Return the number of non-'Nothing' 'node_content's in the given 'TreeMap'.
+-- | Return the number of non-'Nothing' 'node_value's in the given 'TreeMap'.
+--
+-- * Complexity: O(r) where r is the size of the root 'Data.Map.Map'.
size :: Ord k => TreeMap k x -> Int
size = Data.Map.foldr ((+) . node_size) 0 . nodes
--- | Return the content (if any) associated with the given 'Path'.
+-- | Return the value (if any) associated with the given 'Path'.
find :: Ord k => Path k -> TreeMap k x -> Maybe x
-find (k:|[]) (TreeMap m) = maybe Nothing node_content $ Data.Map.lookup k m
+find (k:|[]) (TreeMap m) = maybe Nothing node_value $ Data.Map.lookup k m
find (k:|k':ks) (TreeMap m) =
maybe Nothing (find (path k' ks) . node_descendants) $
Data.Map.lookup k m
-- | Return the given accumulator folded by the given function
--- applied on non-'Nothing' 'node_content's
+-- applied on non-'Nothing' 'node_value's
-- from left to right through the given 'TreeMap'.
foldl_with_Path :: Ord k => (a -> Path k -> x -> a) -> a -> TreeMap k x -> a
foldl_with_Path =
-> a -> TreeMap k x -> a
foldp p fct a (TreeMap m) =
Data.Map.foldlWithKey
- (\acc k Node{node_content, node_descendants} ->
+ (\acc k Node{node_value, node_descendants} ->
let p' = path k p in
- let acc' = maybe acc (fct acc (reverse p')) node_content in
+ let acc' = maybe acc (fct acc (reverse p')) node_value in
foldp (k:p) fct acc' node_descendants) a m
-- | Return the given accumulator folded by the given function
--- applied on non-'Nothing' 'Node's and 'node_content's
+-- applied on non-'Nothing' 'Node's and 'node_value's
-- from left to right through the given 'TreeMap'.
foldl_with_Path_and_Node :: Ord k => (a -> Path k -> Node k x -> x -> a) -> a -> TreeMap k x -> a
foldl_with_Path_and_Node =
-> a -> TreeMap k x -> a
foldp p fct a (TreeMap m) =
Data.Map.foldlWithKey
- (\acc k n@Node{node_content, node_descendants} ->
+ (\acc k n@Node{node_value, node_descendants} ->
let p' = path k p in
- let acc' = maybe acc (fct acc (reverse p') n) node_content in
+ let acc' = maybe acc (fct acc (reverse p') n) node_value in
foldp (k:p) fct acc' node_descendants) a m
-- | Return the given accumulator folded by the given function
--- applied on non-'Nothing' 'node_content's
+-- applied on non-'Nothing' 'node_value's
-- from right to left through the given 'TreeMap'.
foldr_with_Path :: Ord k => (Path k -> x -> a -> a) -> a -> TreeMap k x -> a
foldr_with_Path =
-> a -> TreeMap k x -> a
foldp p fct a (TreeMap m) =
Data.Map.foldrWithKey
- (\k Node{node_content, node_descendants} acc ->
+ (\k Node{node_value, node_descendants} acc ->
let p' = path k p in
let acc' = foldp (k:p) fct acc node_descendants in
- maybe acc' (\x -> fct (reverse p') x acc') node_content) a m
+ maybe acc' (\x -> fct (reverse p') x acc') node_value) a m
-- | Return the given accumulator folded by the given function
--- applied on non-'Nothing' 'Node's and 'node_content's
+-- applied on non-'Nothing' 'Node's and 'node_value's
-- from right to left through the given 'TreeMap'.
foldr_with_Path_and_Node :: Ord k => (Path k -> Node k x -> x -> a -> a) -> a -> TreeMap k x -> a
foldr_with_Path_and_Node =
-> a -> TreeMap k x -> a
foldp p fct a (TreeMap m) =
Data.Map.foldrWithKey
- (\k n@Node{node_content, node_descendants} acc ->
+ (\k n@Node{node_value, node_descendants} acc ->
let p' = path k p in
let acc' = foldp (k:p) fct acc node_descendants in
- maybe acc' (\x -> fct (reverse p') n x acc') node_content) a m
+ maybe acc' (\x -> fct (reverse p') n x acc') node_value) a m
-- | Return a 'Data.Map.Map' associating each 'Path'
--- leading to a non-'Nothing' 'node_content' in the given 'TreeMap',
--- with its content mapped by the given function.
+-- leading to a non-'Nothing' 'node_value' in the given 'TreeMap',
+-- with its value mapped by the given function.
flatten :: Ord k => (x -> y) -> TreeMap k x -> Data.Map.Map (Path k) y
flatten =
flat_map []
Data.Map.unions $
(
Data.Map.mapKeysMonotonic (reverse . flip path p) $
- Data.Map.mapMaybe (\Node{node_content=x} -> f <$> x) m
+ Data.Map.mapMaybe (\Node{node_value=x} -> f <$> x) m
) :
Data.Map.foldrWithKey
(\k -> (:) . flat_map (k:p) f . node_descendants)