public
Created

  • Download Gist
NovemberHomework.hs
Haskell
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 58
import Data.Enumerator hiding (map, length, foldl)
import qualified Data.Enumerator.Text as ET
import qualified Data.Enumerator.List as EL
import Data.List (sort)
import qualified Data.Map as M
import Data.Text (Text)
 
 
data Entry = Entry { date :: String
, host :: String
, program :: String
, message :: String
} deriving Show
 
processFile :: IO ()
processFile = run_ syslogIteratee >>= print
 
-- iteratees et al.
 
syslogIteratee :: Iteratee Entry IO ([(Int, String)], Int)
syslogIteratee = entryEnumerator $$ entryIteratee
 
entryEnumerator :: Enumerator Entry IO b
entryEnumerator = syslogEnumerator $= entryParser
 
syslogEnumerator :: Enumerator Text IO b
syslogEnumerator = ET.enumFile "syslog"
 
entryIteratee :: Monad m => Iteratee Entry m ([(Int, String)], Int)
entryIteratee = EL.zipWith top10AndId summariser counter
 
entryParser :: Monad m => Enumeratee Text Entry m b
entryParser = EL.map parseEntry
 
summariser :: Monad m => Iteratee Entry m (M.Map String Int)
summariser = EL.fold updateSummary M.empty
where updateSummary summary entry = M.insertWith' (+) (program entry) 1 summary
 
counter :: Monad m => Iteratee a m Int
counter = EL.fold (\acc _ -> acc + 1) 0
 
-- auxiliary functions
 
parseEntry :: Text -> Entry
parseEntry text = Entry d h p m
where d1:d2:d3:h:p':ms = words $ show text
d = unwords [d1,d2,d3]
p = init p'
m = unwords ms
 
top10AndId :: Ord a => M.Map a Int -> b -> ([(Int, a)], b)
top10AndId m b = (top10 m, b)
 
top10 :: Ord a => M.Map a Int -> [(Int, a)]
top10 = take 10 . reverse . sort . map swap . M.toList
 
swap :: (a, b) -> (b, a)
swap (x, y) = (y, x)

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.