{-# LANGUAGE FlexibleInstances #-} module HaskellWorks.Data.Succinct.Excess.MinMaxExcess0 ( MinMaxExcess0(..) , MaxExcess , MinExcess ) where import qualified Data.Vector.Storable as DVS import Data.Word import HaskellWorks.Data.Bits.BitWise import HaskellWorks.Data.Bits.FixedBitSize type MinExcess = Int type MaxExcess = Int type Excess = Int class MinMaxExcess0 a where minMaxExcess0 :: a -> (MinExcess, Excess, MaxExcess) instance MinMaxExcess0 [Bool] where minMaxExcess0 = go 0 0 0 where go minE maxE e (x:xs) = let ne = if x then e - 1 else e + 1 in go (minE `min` ne) (maxE `max` ne) ne xs go minE maxE e _ = (minE, e, maxE) instance MinMaxExcess0 Word8 where minMaxExcess0 = go 0 0 0 0 where go minE maxE e n w | n < fixedBitSize w = let ne = if w .?. fromIntegral n then e - 1 else e + 1 in go (minE `min` ne) (maxE `max` ne) ne (n + 1) w go minE maxE e _ _ = (minE, e, maxE) instance MinMaxExcess0 Word16 where minMaxExcess0 = go 0 0 0 0 where go minE maxE e n w | n < fixedBitSize w = let ne = if w .?. fromIntegral n then e - 1 else e + 1 in go (minE `min` ne) (maxE `max` ne) ne (n + 1) w go minE maxE e _ _ = (minE, e, maxE) instance MinMaxExcess0 Word32 where minMaxExcess0 = go 0 0 0 0 where go minE maxE e n w | n < fixedBitSize w = let ne = if w .?. fromIntegral n then e - 1 else e + 1 in go (minE `min` ne) (maxE `max` ne) ne (n + 1) w go minE maxE e _ _ = (minE, e, maxE) instance MinMaxExcess0 Word64 where minMaxExcess0 = go 0 0 0 0 where go minE maxE e n w | n < fixedBitSize w = let ne = if w .?. fromIntegral n then e - 1 else e + 1 in go (minE `min` ne) (maxE `max` ne) ne (n + 1) w go minE maxE e _ _ = (minE, e, maxE) instance MinMaxExcess0 (DVS.Vector Word8) where minMaxExcess0 = DVS.foldl gen (0, 0, 0) where gen :: (MinExcess, Excess, MaxExcess) -> Word8 -> (MinExcess, Excess, MaxExcess) gen (minE, e, maxE) w = let (wMinE, wE, wMaxE) = minMaxExcess0 w in (minE `min` (wMinE + e), e + wE, maxE `max` (wMaxE + e)) instance MinMaxExcess0 (DVS.Vector Word16) where minMaxExcess0 = DVS.foldl gen (0, 0, 0) where gen :: (MinExcess, Excess, MaxExcess) -> Word16 -> (MinExcess, Excess, MaxExcess) gen (minE, e, maxE) w = let (wMinE, wE, wMaxE) = minMaxExcess0 w in (minE `min` (wMinE + e), e + wE, maxE `max` (wMaxE + e)) instance MinMaxExcess0 (DVS.Vector Word32) where minMaxExcess0 = DVS.foldl gen (0, 0, 0) where gen :: (MinExcess, Excess, MaxExcess) -> Word32 -> (MinExcess, Excess, MaxExcess) gen (minE, e, maxE) w = let (wMinE, wE, wMaxE) = minMaxExcess0 w in (minE `min` (wMinE + e), e + wE, maxE `max` (wMaxE + e)) instance MinMaxExcess0 (DVS.Vector Word64) where minMaxExcess0 = DVS.foldl gen (0, 0, 0) where gen :: (MinExcess, Excess, MaxExcess) -> Word64 -> (MinExcess, Excess, MaxExcess) gen (minE, e, maxE) w = let (wMinE, wE, wMaxE) = minMaxExcess0 w in (minE `min` (wMinE + e), e + wE, maxE `max` (wMaxE + e))