module Data.Binary.Enum where
import Prelude
import Data.Binary
import Control.Applicative
import qualified Data.List as DL
newtype BitMap t a = BitMap [a]
newtype BitEnc t a = BitEnc a
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