binary-enum-0.1.0.0: Data/Binary/Enum.hs
{-# LANGUAGE ViewPatterns, ScopedTypeVariables #-}
module Data.Binary.Enum where
import Prelude
import Data.Binary
import Control.Applicative
import qualified Data.List as DL
-- | we can store Enum values inside values we know how to store, so let
newtype BitMap t a = BitMap [a]
-- ^ Map lets you encode 'flags' compressing distinct eg. packing 8 diferent flags per byte
newtype BitEnc t a = BitEnc a
-- ^ t is a store type, you will need to make sure thats your enum fits there
instance (Enum a, Enum t, Binary t) => Binary (BitEnc t a) where
put (BitEnc a) = put (toEnum . fromEnum $ a :: t)
get = BitEnc . toEnum . fromEnum <$> (get :: Get t)
instance (Enum a, Eq a, Eq t, Num t, Integral t, Binary t) => Binary (BitMap t a) where
put (BitMap a) = put ( foldr (\(fromEnum -> x) y -> 2 ^ x + y ) 0 (DL.nub a) :: t )
get = BitMap . process 0 <$> (get :: Get t)
where
process _ 0 = []
process k (flip divMod 2 -> (d, m))
| m == 1 = toEnum k : process (k + 1) d
| otherwise = process (k + 1) d