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]
deriving instance (Show a) => Show (BitMap t a)
newtype BitEnc t a = BitEnc a
deriving instance (Show a) => Show (BitEnc t 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, Integral t, Binary t) => Binary (BitMap t a) where
put a = put ( (toEnum (fromEnum a)) :: t )
get = toEnum . fromEnum <$> (get :: Get t)
instance (Enum a, Enum t, Eq a, Eq t, Num t) => Enum (BitMap t a) where
fromEnum (BitMap a) = fromEnum (foldr (\(fromEnum -> x) y -> 2 ^ x + y ) 0 (DL.nub a) :: t)
toEnum = BitMap . process 0
where
process _ 0 = []
process k (flip divMod 2 -> (d, m))
| m == 1 = toEnum k : process (k + 1) d
| otherwise = process (k + 1) d
instance (Enum a, Enum t, Binary t) => Enum (BitEnc t a) where
fromEnum (BitEnc a) = fromEnum a
toEnum = BitEnc . toEnum . fromEnum