Hi Nicolas, The simplest approach would be to use the standard (derived) Enum instance that would be used for enumerations (like [Flag1..]), and have your own functions to convert to/from magic constants.
Roman * Nicolas Trangez <[email protected]> [2012-11-17 15:44:57+0100] > 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! _______________________________________________ Haskell-Cafe mailing list [email protected] http://www.haskell.org/mailman/listinfo/haskell-cafe
