-
Notifications
You must be signed in to change notification settings - Fork 3
/
WordCount.hs
57 lines (47 loc) · 1.94 KB
/
WordCount.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
-- To run this program:
--
-- cabal run --flag fusion-plugin WordCount test-data.txt
--
module WordCount (main, count, Counts(..), isSpace) where
import Data.Char (ord)
import Data.Function ((&))
import System.Environment (getArgs)
import qualified Streamly.Data.Fold as Fold
import qualified Streamly.Data.Stream as Stream
import qualified Streamly.FileSystem.File as File
import qualified Streamly.Unicode.Stream as Stream
-------------------------------------------------------------------------------
-- C compatible isSpace
-------------------------------------------------------------------------------
{-# INLINE isSpace #-}
isSpace :: Char -> Bool
isSpace c = uc == 0x20 || uc - 0x9 <= 4
where uc = fromIntegral (ord c) :: Word
-------------------------------------------------------------------------------
-- Counting
-------------------------------------------------------------------------------
-- Counts lines words chars lastCharWasSpace
data Counts = Counts !Int !Int !Int !Bool deriving Show
{-# INLINE count #-}
count :: Counts -> Char -> Counts
count (Counts l w c wasSpace) ch =
let l1 = if ch == '\n' then l + 1 else l
(w1, wasSpace1) =
if isSpace ch
then (w, True)
else (if wasSpace then w + 1 else w, False)
in Counts l1 w1 (c + 1) wasSpace1
wc :: String -> IO Counts
wc file =
File.read file -- Stream IO Word8
& Stream.decodeLatin1 -- Stream IO Char
-- & Stream.decodeUtf8 -- Stream IO Char
& Stream.fold (Fold.foldl' count (Counts 0 0 0 True)) -- IO Counts
-------------------------------------------------------------------------------
-- Main
-------------------------------------------------------------------------------
main :: IO ()
main = do
name <- fmap head getArgs
Counts l w c _ <- wc name
putStrLn $ show l ++ " " ++ show w ++ " " ++ show c ++ " " ++ name