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 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