module Trie where import qualified Data.Map as Map import Data.Maybe(fromMaybe) data Trie a b = Sub (Map.Map a (Trie a b)) (Maybe b) deriving Show empty :: Trie a b empty = Sub Map.empty Nothing lookup :: Ord a => [a] -> Trie a b -> Maybe b lookup [] (Sub _ b) = b lookup (k:ks) (Sub as _) = Trie.lookup ks =<< Map.lookup k as insert :: (Ord a) => [a] -> (Maybe b -> b) -> Trie a b -> Trie a b insert [] f (Sub as b) = Sub as (Just (f b)) insert (k:ks) f (Sub as b) = Sub (Map.alter upd k as) b where upd j = Just $ insert ks f $ fromMaybe empty j