bloom/Main.hs

56 lines
1.4 KiB
Haskell
Raw Normal View History

2020-11-13 14:49:01 +00:00
{-# language TypeApplications #-}
{-# language DataKinds #-}
2020-11-14 12:37:37 +00:00
{-# language LambdaCase #-}
2020-11-13 14:49:01 +00:00
{-# 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
2020-11-14 12:37:37 +00:00
import Control.Monad (guard)
2020-11-13 14:49:01 +00:00
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
2020-11-14 12:37:37 +00:00
load cache >>= \case
Nothing -> do
b <- build
ByteString.writeFile cache $ Binary.encode b
pure b
Just a -> pure a
2020-11-13 14:49:01 +00:00
getCachePath :: IO FilePath
getCachePath = (</> "bloom-spell/words.bin") <$> getEnv "XDG_DATA_HOME"
2020-11-14 12:37:37 +00:00
load :: FilePath -> IO (Maybe (Bloom Size String))
load p = do
cacheExists <- doesFileExist p
guard cacheExists
s <- ByteString.readFile p
case Binary.decodeOrFail @(Bloom Size _) s of
Left{} -> pure Nothing
Right (_, _, a) -> pure $ pure a
2020-11-13 14:49:01 +00:00
build :: IO (Bloom Size String)
build = fromList @(Bloom Size _) . lines <$> readFile dict
2020-11-14 12:37:37 +00:00
type Size = 0xffff0
2020-11-13 14:49:01 +00:00
dict :: FilePath
dict = "/usr/share/dict/words"