module Wordify.Rules.Dictionary (Dictionary, isValidWord, makeDictionary, invalidWords, dictionaryFromWords) where
import qualified Data.HashSet as HashSet
import Wordify.Rules.ScrabbleError
import qualified Control.Exception as Exc
import Text.ParserCombinators.Parsec
import Data.Char
import Control.Monad
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 wordList = Dictionary $ HashSet.fromList upperCaseWords
where
upperCaseWords = (map . map) toUpper wordList
makeDictionary :: FilePath -> IO (Either ScrabbleError Dictionary)
makeDictionary filePath =
do
fileContents <- Exc.try (readFile filePath) :: IO (Either Exc.IOException String)
case fileContents of
Left _ -> return $ Left (DictionaryFileNotFound filePath)
Right dictContents ->
let dictWords = parseFile dictContents
in case dictWords of
Left _ -> return $ Left (MalformedDictionaryFile filePath)
Right wordList -> return $ Right (Dictionary $ HashSet.fromList wordList)
where
toUpperCase = (map . map) toUpper
parseFile contents = liftM toUpperCase $ parse dictionaryFile "Malformed dictionary file " contents
dictionaryFile =
do
dictWords <- many word
_ <- eof
return dictWords
word =
do
entry <- many letter
_ <- newline
return entry