syfco-1.1.0.0: src/Data/StringMap.hs
-----------------------------------------------------------------------------
-- |
-- Module : Data.StringMap
-- License : MIT (see the LICENSE file)
-- Maintainer : Felix Klein (klein@react.uni-saarland.de)
--
-- A simple data structure to map strings to integers.
--
-----------------------------------------------------------------------------
module Data.StringMap
( StringMap
, empty
, lookup
, insert
) where
-----------------------------------------------------------------------------
import Prelude hiding (lookup)
-----------------------------------------------------------------------------
-- | Internal data structure of the mapping.
data StringMap =
Empty
| Leaf (String, Int)
| Node (Maybe Int, [(Char, StringMap)])
-----------------------------------------------------------------------------
-- | Returns the empty mapping.
empty
:: StringMap
empty = Empty
-----------------------------------------------------------------------------
-- | Lookups a string in the mapping.
lookup
:: String -> StringMap -> Maybe Int
lookup str mapping = case mapping of
Empty -> Nothing
Leaf (e,v) -> if e == str then Just v else Nothing
Node (v,xs) -> case str of
[] -> v
x:xr -> case findMatch x xs of
Just mapping' -> lookup xr mapping'
_ -> Nothing
where
findMatch x xs = case xs of
[] -> Nothing
((y,n) : xr) -> if x == y then Just n
else findMatch x xr
-----------------------------------------------------------------------------
-- | Inserts a new string-int pair to the given mapping. If the mapping
-- already containts the given string, then the corresponding value is
-- updated.
insert
:: String -> Int -> StringMap -> StringMap
insert s i m = case m of
Empty -> Leaf (s,i)
Leaf (e,v) -> if e == s then Leaf (s,i) else case e of
[] -> Node (Just v, [(head s, Leaf (tail s,i))])
(x:xr) -> case s of
[] -> Node (Just i, [(x,Leaf (xr,v))])
(y:yr) ->
if x == y then
Node (Nothing, [(x, insert yr i (Leaf (xr,v)))])
else
Node (Nothing, [(x, Leaf (xr,v)),(y, Leaf (yr,i))])
Node (v,xs) -> case s of
[] -> Node (Just i,xs)
(x:xr) -> Node (v, add x xr i xs)
where
add x xr j xs = case xs of
[] -> [(x, Leaf (xr,j))]
((c,n):yr) ->
if x == c then
(c,insert xr j n):yr
else
(c,n) : add x xr j yr
-----------------------------------------------------------------------------