module WalkTrie ( processText , aggregateResults ) where import Control.Arrow ((&&&)) import qualified Data.HashMap.Strict as Map import qualified Data.Maybe as M import qualified Data.Text as T import Trie data WalkedNode = Unwalked Trie | Walked String Node deriving (Show) aggregateResults :: [Map.HashMap String Int] -> Map.HashMap String Int aggregateResults = foldl1 (Map.unionWith (+)) processText :: Trie -> T.Text -> Map.HashMap String Int processText trie = snd . T.foldl f ([], Map.empty) where newTrie char = case findNodeFromTrie trie char of Nothing -> [] Just _ -> [Unwalked trie] f (state, map') char = advanceStates char map' $ newTrie char ++ state advanceStates :: Char -> Map.HashMap String Int -> [WalkedNode] -> ([WalkedNode], Map.HashMap String Int) advanceStates char map' = (id &&& foldl newMap map' . concatMap walkedTerminalResult) . M.mapMaybe (walk char) where newMap m word = Map.insertWith (+) word 1 m walk :: Char -> WalkedNode -> Maybe WalkedNode walk char (Unwalked trie) = case findNodeFromTrie trie char of Nothing -> Nothing Just node' -> Just $ Walked [char] node' walk char (Walked string node) = case findNodeFromChildren node char of Nothing -> Nothing Just node' -> Just $ Walked (string ++ [char]) node' walkedTerminalResult :: WalkedNode -> [String] walkedTerminalResult (Walked base node) = [base | isTerminal node] walkedTerminalResult _ = []