module Data.StringMap.Strict
(
StringMap()
, Key
, (!)
, value
, valueWithDefault
, null
, size
, member
, lookup
, findWithDefault
, prefixFind
, prefixFindWithKey
, prefixFindWithKeyBF
, lookupRange
, empty
, singleton
, insert
, insertWith
, insertWithKey
, adjust
, adjustWithKey
, delete
, update
, updateWithKey
, union
, unionWith
, unionMapWith
, unionWithKey
, difference
, differenceWith
, differenceWithKey
, intersection
, intersectionWith
, map
, mapWithKey
, mapM
, mapWithKeyM
, mapMaybe
, fold
, foldWithKey
, foldr
, foldrWithKey
, foldl
, foldlWithKey
, keys
, elems
, fromList
, toList
, toListShortestFirst
, fromMap
, toMap
, prefixFilter
, prefixFilterNoCase
, lookupNoCase
)
where
import Data.StringMap.Base hiding (adjust, adjustWithKey,
delete, fromList, insert,
insertWith, insertWithKey, map,
mapM, mapMaybe, mapWithKey,
mapWithKeyM, singleton, union,
unionWith, unionMapWith, update, updateWithKey)
import qualified Data.StringMap.Base as Base
import Data.StringMap.FuzzySearch
import Prelude hiding (foldl, foldr, lookup, map,
mapM, null, succ)
import qualified Data.List as L
normError :: String -> a
normError = normError' "Data.StringMap.Strict"
singleton :: Key -> a -> StringMap a
singleton k !v = Base.singleton k v
insert :: Key -> a -> StringMap a -> StringMap a
insert !k !v = insertWith const k v
insertWith :: (a -> a -> a) -> Key -> a -> StringMap a -> StringMap a
insertWith f !k v t = insert' f v k t
insertWithKey :: (Key -> a -> a -> a) -> Key -> a -> StringMap a -> StringMap a
insertWithKey f !k = insertWith (f k) k
update :: (a -> Maybe a) -> Key -> StringMap a -> StringMap a
update = update'
updateWithKey :: (Key -> a -> Maybe a) -> Key -> StringMap a -> StringMap a
updateWithKey f k = update' (f k) k
delete :: Key -> StringMap a -> StringMap a
delete = update' (const Nothing)
adjust :: (a -> a) -> Key -> StringMap a -> StringMap a
adjust f = update' (Just . f)
adjustWithKey :: (Key -> a -> a) -> Key -> StringMap a -> StringMap a
adjustWithKey f k = update' (Just . f k) k
insert' :: (a -> a -> a) -> a -> Key -> StringMap a -> StringMap a
insert' f v k0 = ins k0 . norm
where
ins' = insert' f v
ins k (Branch c' s' n')
= case k of
[] -> val v (branch c' s' n')
(c : k1)
| c < c' -> branch c (singleton k1 v) (branch c' s' n')
| c == c' -> branch c (ins' k1 s') n'
| otherwise -> branch c' s' (ins' k n')
ins k Empty = singleton k v
ins k (Val v' t')
= case k of
[] -> flip val t' $! f v v'
_ -> val v' (ins' k t')
ins _ _ = normError "insert'"
update' :: (a -> Maybe a) -> Key -> StringMap a -> StringMap a
update' f k0 = upd k0 . norm
where
upd' = update' f
upd k (Branch c' s' n')
= case k of
[] -> branch c' s' n'
(c : k1)
| c < c' -> branch c' s' n'
| c == c' -> branch c (upd' k1 s') n'
| otherwise -> branch c' s' (upd' k n')
upd _ Empty = empty
upd k (Val v' t')
= case k of
[] -> case f v' of
Nothing -> t'
Just !v'' -> val v'' t'
_ -> val v' (upd' k t')
upd _ _ = normError "update'"
union :: StringMap a -> StringMap a -> StringMap a
union = union' const
unionWith :: (a -> a -> a) -> StringMap a -> StringMap a -> StringMap a
unionWith = union'
union' :: (a -> a -> a) -> StringMap a -> StringMap a -> StringMap a
union' f pt1 pt2 = uni (norm pt1) (norm pt2)
where
uni' t1' t2' = union' f (norm t1') (norm t2')
uni Empty Empty = empty
uni Empty (Val v2 t2) = val v2 t2
uni Empty (Branch c2 s2 n2)
= branch c2 s2 n2
uni (Val v1 t1) Empty = val v1 t1
uni (Val v1 t1) (Val v2 t2) = (val $! f v1 v2) (uni' t1 t2)
uni (Val v1 t1) t2@(Branch _ _ _) = val v1 (uni' t1 t2)
uni (Branch c1 s1 n1) Empty = branch c1 s1 n1
uni t1@(Branch _ _ _ ) (Val v2 t2) = val v2 (uni' t1 t2)
uni t1@(Branch c1 s1 n1) t2@(Branch c2 s2 n2)
| c1 < c2 = branch c1 s1 (uni' n1 t2)
| c1 > c2 = branch c2 s2 (uni' t1 n2)
| otherwise = branch c1 (uni' s1 s2) (uni' n1 n2)
uni _ _ = normError "union'"
unionMapWith :: (b -> a) -> (a -> b -> a) -> StringMap a -> StringMap b -> StringMap a
unionMapWith = unionG'
unionG' :: (b -> a) -> (a -> b -> a) -> StringMap a -> StringMap b -> StringMap a
unionG' to f pt1 pt2 = uni (norm pt1) (norm pt2)
where
uni' t1' t2' = unionG' to f (norm t1') (norm t2')
uni Empty Empty = empty
uni Empty (Val v2 t2) = (val $! (to v2)) (map to t2)
uni Empty (Branch c2 s2 n2)
= branch c2 (map to s2) (map to n2)
uni (Val v1 t1) Empty = val v1 t1
uni (Val v1 t1) (Val v2 t2) = (val $! (f v1 v2)) (uni' t1 t2)
uni (Val v1 t1) t2@(Branch _ _ _) = val v1 (uni' t1 t2)
uni (Branch c1 s1 n1) Empty = branch c1 s1 n1
uni t1@(Branch _ _ _ ) (Val v2 t2) = (val $! (to v2)) (uni' t1 t2)
uni t1@(Branch c1 s1 n1) t2@(Branch c2 s2 n2)
| c1 < c2 = branch c1 s1 (uni' n1 t2)
| c1 > c2 = branch c2 (map to s2) (uni' t1 n2)
| otherwise = branch c1 (uni' s1 s2) (uni' n1 n2)
uni _ _ = normError "union'"
map :: (a -> b) -> StringMap a -> StringMap b
map f = mapWithKey (const f)
mapWithKey :: (Key -> a -> b) -> StringMap a -> StringMap b
mapWithKey f = map' f id
map' :: (Key -> a -> b) -> (Key -> Key) -> StringMap a -> StringMap b
map' _ _ (Empty) = Empty
map' f k (Val v t) = (Val $! (f (k []) v)) (map' f k t)
map' f k (Branch c s n) = Branch c (map' f ((c :) . k) s) (map' f k n)
map' f k (Leaf v) = Leaf $! (f (k []) v)
map' f k (Last c s) = Last c (map' f ((c :) . k) s)
map' f k (LsSeq cs s) = LsSeq cs (map' f ((toKey cs ++) . k) s)
map' f k (BrSeq cs s n) = BrSeq cs (map' f ((toKey cs ++) . k) s) (map' f k n)
map' f k (LsSeL cs v) = LsSeL cs $! (f (k []) v)
map' f k (BrSeL cs v n) =(BrSeL cs $! (f (k []) v)) (map' f k n)
map' f k (LsVal c v) = LsVal c $! (f (k []) v)
map' f k (BrVal c v n) =(BrVal c $! (f (k []) v)) (map' f k n)
mapMaybe :: (a -> Maybe b) -> StringMap a -> StringMap b
mapMaybe = mapMaybe'
mapMaybe' :: (a -> Maybe b) -> StringMap a -> StringMap b
mapMaybe' f = upd . norm
where
upd' = mapMaybe' f
upd (Branch c' s' n') = branch c' (upd' s') (upd' n')
upd Empty = empty
upd (Val v' t') = case f v' of
Nothing -> t
Just !v'' -> val v'' t
where t = upd' t'
upd _ = normError "update'"
mapM :: Monad m => (a -> m b) -> StringMap a -> m (StringMap b)
mapM f = mapWithKeyM (const f)
mapWithKeyM :: Monad m => (Key -> a -> m b) -> StringMap a -> m (StringMap b)
mapWithKeyM f = mapM'' f id
mapM'' :: Monad m => (Key -> a -> m b) -> (Key -> Key) -> StringMap a -> m (StringMap b)
mapM'' f k = mapn . norm
where
mapn' = mapM'' f
mapn Empty = return $ empty
mapn (Val v t) = do
!v' <- f (k []) v
t' <- mapn' k t
return $ val v' t'
mapn (Branch c s n) = do
s' <- mapn' ((c :) . k) s
n' <- mapn' k n
return $ branch c s' n'
mapn _ = normError "mapM''"
fromList :: [(Key, a)] -> StringMap a
fromList = L.foldl' (\p (k, v) -> insert k v p) empty