Entropy.hs (1034B)
1 {-# OPTIONS_GHC -Wall #-} 2 {-# OPTIONS_GHC -fno-warn-type-defaults #-} 3 {-# OPTIONS_GHC -fno-warn-unused-binds #-} 4 5 import Control.Foldl (Fold (..)) 6 import qualified Control.Foldl as L 7 import Data.Map.Strict (Map) 8 import qualified Data.Map.Strict as Map 9 import Pipes ((>->)) 10 import qualified Pipes.ByteString as P 11 12 group :: (Ord k, Num a) => Fold k (Map k a) 13 group = Fold step mempty id where 14 step m k = Map.insertWith (+) k 1 m 15 16 distribution :: (Ord k, Fractional a) => Fold k (Map k a) 17 distribution = divide <$> group <*> L.genericLength where 18 divide m n = fmap (/ n) m 19 20 entropize :: Floating a => a -> a 21 entropize m = negate (m * logBase 2 m) 22 23 entropy :: (Foldable f, Ord k, Floating a) => f k -> a 24 entropy = L.fold (L.premap entropize L.sum) . L.fold distribution 25 26 main :: IO () 27 main = do 28 let source = P.stdin >-> P.filter (/= 10) 29 dist <- case distribution of 30 Fold step start extract -> P.foldBytes step start extract source 31 print $ L.fold L.sum (fmap entropize dist) 32