@@ -0,0 +1,41 @@
1+-- compile with:
2+-- ghc -O2 -fspec-constr-recursive=10 -fmax-worker-args=16 word-classifier.hs
3+--
4+import qualified Data.Char as Char
5+import Data.Foldable
6+import Data.Function ((&))
7+import Data.Functor.Identity (Identity(..))
8+import qualified Data.HashMap.Strict as Map
9+import Data.Hashable
10+import qualified Data.List as List
11+import qualified Data.Ord as Ord
12+import Foreign.Storable (Storable(..))
13+import qualified Streamly.Data.String as Streamly
14+import qualified Streamly.FileSystem.Handle as FH
15+import qualified Streamly.Internal as Streamly
16+import qualified Streamly.Memory.Array as A
17+import qualified Streamly.Prelude as Streamly
18+import System.Environment (getArgs)
19+import System.IO (openFile, IOMode(..))
20+
21+instance (Enum a, Storable a) => Hashable (A.Array a) where
22+ hash arr = runIdentity $ Streamly.runFold Streamly.rollingHash (A.read arr)
23+ hashWithSalt salt arr = runIdentity $
24+ Streamly.runFold (Streamly.rollingHashWithSalt salt) (A.read arr)
25+
26+main :: IO ()
27+main =
28+ let
29+ increment m str = Map.insertWith (+) str (1 :: Int) m
30+ report = traverse_ print
31+ in do
32+ name <- fmap head getArgs
33+ src <- openFile name ReadMode
34+ FH.read src -- SerialT IO Word8
35+ & Streamly.decodeChar8 -- SerialT IO Char
36+ & Streamly.map Char.toLower -- SerialT IO Char
37+ & Streamly.words -- SerialT IO (Array Char)
38+ & Streamly.filterM (Streamly.all Char.isAlpha . A.read)
39+ & Streamly.foldl' increment Map.empty
40+ & fmap (List.take 25 . List.sortOn (Ord.Down . snd) . Map.toList)
41+ >>= report -- IO ()