49 lines
1.2 KiB
Haskell
49 lines
1.2 KiB
Haskell
{-# language TypeApplications #-}
|
|
{-# language DataKinds #-}
|
|
{-# options_ghc -Wall -Werror #-}
|
|
module Main (main) where
|
|
|
|
import GHC.Exts (IsList(..))
|
|
import Data.Foldable (traverse_)
|
|
import System.Exit (ExitCode(ExitSuccess, ExitFailure), exitWith)
|
|
import Bloom (Bloom)
|
|
import qualified Bloom
|
|
import qualified Data.Binary as Binary
|
|
import qualified Data.ByteString.Lazy as ByteString
|
|
import System.Directory
|
|
import System.FilePath
|
|
import System.Environment
|
|
|
|
main :: IO ()
|
|
main = do
|
|
b <- cachedLoad
|
|
input <- lines <$> getContents
|
|
let ws' = filter (not . (`Bloom.elem` b)) input
|
|
traverse_ putStrLn ws'
|
|
exitWith (if null ws' then ExitSuccess else ExitFailure 1)
|
|
|
|
cachedLoad :: IO (Bloom Size String)
|
|
cachedLoad = do
|
|
cache <- getCachePath
|
|
cacheExists <- doesFileExist cache
|
|
if cacheExists
|
|
then load cache
|
|
else do
|
|
b <- build
|
|
ByteString.writeFile cache $ Binary.encode b
|
|
pure b
|
|
|
|
getCachePath :: IO FilePath
|
|
getCachePath = (</> "bloom-spell/words.bin") <$> getEnv "XDG_DATA_HOME"
|
|
|
|
load :: FilePath -> IO (Bloom Size String)
|
|
load p = Binary.decode @(Bloom Size _) <$> ByteString.readFile p
|
|
|
|
build :: IO (Bloom Size String)
|
|
build = fromList @(Bloom Size _) . lines <$> readFile dict
|
|
|
|
type Size = 0xfffff
|
|
|
|
dict :: FilePath
|
|
dict = "/usr/share/dict/words"
|