module Wordify.Rules.Dictionary (Dictionary,
makeDictionary,
dictionaryFromWords,
isValidWord,
invalidWords
) where
import qualified Data.HashSet as HashSet
import Wordify.Rules.ScrabbleError
import qualified Control.Exception as Exc
import Text.ParserCombinators.Parsec
import Text.Parsec.Prim
import Data.Char
import Control.Monad
import Control.Arrow
data Dictionary = Dictionary (HashSet.HashSet String) deriving Show
invalidWords :: Dictionary -> [String] -> [String]
invalidWords dictionary = filter $ not . isValidWord dictionary
isValidWord :: Dictionary -> String -> Bool
isValidWord (Dictionary dictionaryWords) = flip HashSet.member dictionaryWords
dictionaryFromWords :: [String] -> Dictionary
dictionaryFromWords = Dictionary . HashSet.fromList . upperCaseWords
makeDictionary :: FilePath -> IO (Either ScrabbleError Dictionary)
makeDictionary filePath = join . fmap parseDictionary <$> readDictionaryFile filePath
readDictionaryFile :: FilePath -> IO (Either ScrabbleError String)
readDictionaryFile filePath = convertFileError <$> (Exc.try (readFile filePath) :: (IO (Either Exc.IOException String)))
where
convertFileError = left (\_ -> DictionaryFileNotFound filePath)
parseDictionary :: String -> Either ScrabbleError Dictionary
parseDictionary = either (Left . MalformedDictionaryFile . show) (Right . dictionaryFromWords) . parseFile
where
parseFile = parse dictionaryFile ""
dictionaryFile =
do
dictWords <- many word
_ <- eof
return dictWords
word =
do
entry <- many letter :: Parser String
_ <- newline
return entry
upperCaseWords :: [String] -> [String]
upperCaseWords = (map . map) toUpper