Created
May 10, 2014 07:09
-
-
Save etrepum/d030f4efb2c7a13fd987 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE OverloadedStrings, BangPatterns #-} | |
module Megahaskhal.Dictionary ( | |
Dictionary, | |
addWord, | |
addAllWords, | |
findWord, | |
lookupIndex, | |
replicateM, | |
forM_, | |
emptyDictionary, | |
length ) where | |
import qualified Data.Foldable as F | |
import qualified Data.Map.Strict as M | |
import qualified Data.IntMap.Strict as I | |
import Data.Text (Text) | |
import Prelude hiding (length) | |
import Control.DeepSeq (NFData) | |
data Dictionary = Dictionary | |
{ dWordId :: !(M.Map Text Int) | |
, dIdWord :: !(I.IntMap Text) | |
} deriving (Show) | |
instance NFData Dictionary | |
forM_ :: Monad m => Dictionary -> (Text -> m a) -> m () | |
forM_ d m = mapM_ (m . findWord d) [0 .. length d] | |
emptyDictionary :: Dictionary | |
emptyDictionary = addAllWords (Dictionary M.empty I.empty) defaultWords | |
where defaultWords = ["<ERROR>", "<FIN>"] | |
findWord :: Dictionary -> Int -> Text | |
findWord = (I.!) . dIdWord | |
lookupIndex :: Text -> Dictionary -> Maybe Int | |
lookupIndex k = M.lookup k . dWordId | |
addWord :: Text -> Dictionary -> (Int, Dictionary) | |
addWord s (Dictionary wordId idWord) = | |
case M.lookup s wordId of | |
Just ident -> (ident, dict) | |
Nothing -> (len, dict) | |
where | |
len = M.size wordId | |
dict = Dictionary (M.insert s len wordId) (I.insert len s idWord) | |
-- |Add all words to a dictionary if they weren't already in it, and return | |
-- the new dictionary | |
addAllWords :: Dictionary -> [Text] -> Dictionary | |
addAllWords = F.foldl' go | |
where go d w = snd $ addWord w d | |
replicateM :: Monad m => Int -> m Text -> m Dictionary | |
replicateM reps m = go reps emptyDictionary | |
where | |
go n !acc | |
| n <= 0 = return acc | |
| otherwise = m >>= go (n - 1) . snd . (`addWord` acc) | |
length :: Dictionary -> Int | |
length = M.size . dWordId |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Before
After