(newbie) instance Enum MyType where, smarter way?

-----BEGIN PGP SIGNED MESSAGE----- Hash: RIPEMD160 Hello, I defined an enumeration datatype like this data MyType = One | Two | Four | Eight and want to make it an instance of the class Enum. deriving Enum won't do what I want, as it labels the items 0,1,2,3. Is there a better way to do this than instance Enum MyType where fromEnum One = 1 fromEnum Two = 2 ... toEnum 8 = Eight Something like instance Enum MyType where fromEnum One = 1 fromEnum x = 2*pred x toEnum 1 = One toEnum x = succ (toEnum x `div` 2) Which doesn't work because succ and pred are not (properly?) defined. Is there a way to let deriving Enum do *some* of work (i.e. defining succ and pred) while manually defining the other functions? -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFGCTRJ11V8mqIQMRsRA4GFAJwKaxQoKdEW91pHUskzJadDvh7lXgCeLg6P dmQKcjRZEg4fqoZfQ4jOuhg= =RWQ+ -----END PGP SIGNATURE-----

On Tuesday 27 March 2007 17:15, Adrian Neumann wrote:
[...] Which doesn't work because succ and pred are not (properly?) defined. Is there a way to let deriving Enum do *some* of work (i.e. defining succ and pred) while manually defining the other functions?
Hmmm, this seems to be a confusing usage of the Enum class, e.g. 'fromEnum . toEnum' changes some values (allowed by the report, but confusing nevertheless). Using Data.Bits.Bits somehow could be a better option, but one has to know more about your use case. Cheers, S.

Adrian Neumann wrote:
I defined an enumeration datatype like this
data MyType = One | Two | Four | Eight
and want to make it an instance of the class Enum. deriving Enum won't do what I want, as it labels the items 0,1,2,3. Is there a better way to do this than
Define them as deriving Enum. Now on top of this define bitValue :: MyType -> Int bitValue m = 2^(fromEnum m) and, if you need it, the converse. Or even something neater which splits a number into an array of constructors corresponding to bitnums manyValues :: [MyType] -> Int manyValues = foldr (.|.) . map bitValue -- you need Data.Bits for the bitwise or, .|. fromInt :: Int -> [MyType] fromInt i = filter (\n -> i .&. (bitValue n) > 0) [One..Eight] Of course, I'm taking the liberty of guessing here that you're modelling binary-flags-as-bitfields Jules
participants (3)
-
Adrian Neumann
-
Jules Bean
-
Sven Panne