All, I've been working on a server implementation of an existing networking protocol. The protocol uses "magic constants" in some places (e.g. to tag message types), as well as bitfields, or a combination of both packed in a single value.
I created data types for both the identifiers as well as the bitfield masks, e.g. > import Data.Bits > data MessageType = Message1 > | Message2 > | Message5 > data MessageFlag = Flag1 > | Flag2 Since I need to be able to get a numeric representation of them, I thought making a custom Enum instance would make sense: > instance Enum MessageType where > fromEnum a = case a of > Message1 -> 1 > Message2 -> 2 > Message5 -> 5 > toEnum n > | n == 1 = Message1 > | n == 2 = Message2 > | n == 5 = Message5 > instance Enum MessageFlag where > fromEnum a = case a of > Flag1 -> 1 `shiftL` 0 > Flag2 -> 1 `shiftL` 1 > toEnum n > | n == 1 `shiftL` 0 = Flag1 > | n == 1 `shiftL` 1 = Flag2 This is not a complete definition (not to mention non-exhaustive pattern matches), so I was wondering what the best practices are to extend this so these instances are 'correct'? I've been trying several approaches, but all of them failed on code like > getFlags :: Int -> [MessageFlag] > getFlags i = filter (\v -> (i .&. fromEnum v) /= 0) [Flag1 ..] Unless I hard-code all options in the last list, of course, but this is obviously not the intention. Any help or pointers (including "This is not how Enum is intended to be used") would be appreciated! Thanks, Nicolas _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe