Re: [Haskell-cafe] Custom Enum instance with non-consecutive indices

2012-11-17 Thread Roman Cheplyaka
* Nicolas Trangez  [2012-11-17 16:23:28+0100]
> On Sat, 2012-11-17 at 16:52 +0200, Roman Cheplyaka wrote:
> > 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. 
> 
> Sure, but that kind-of defeats the purpose... fromEnum/toEnum would then
> return some nonsensical integer value.

What's your purpose, exactly? I see two of them — being able to use
enumerations, and converting from/to magical constants.

If you want to use toEnum/fromEnum for conversions so badly, you can
leave them as you defined them, but redefine the enumFrom* methods from
the Enum class.

But I'd still advise that you do your conversion outside of the Enum
class, since such instance would be very unintuitive to someone who
reads or uses your code.

BTW, the value of the derived fromEnum is not nonsensical — it
determines where in the [Flag1..] list a particular flag would appear.

Roman

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Custom Enum instance with non-consecutive indices

2012-11-17 Thread Nicolas Trangez
On Sat, 2012-11-17 at 16:27 +0100, Herbert Valerio Riedel wrote:
> what do you hope to gain from making your flags type an instance of
> the
> Enum class? 

Among others, the ability to list all flags using "[Flag1 ..]"

How is this handled for libraries wrapping C libs which use some bitset
structure?

Nicolas


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Custom Enum instance with non-consecutive indices

2012-11-17 Thread Herbert Valerio Riedel
Nicolas Trangez  writes:

> On Sat, 2012-11-17 at 16:52 +0200, Roman Cheplyaka wrote:
>> 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. 
>
> Sure, but that kind-of defeats the purpose... fromEnum/toEnum would then
> return some nonsensical integer value.

...then don't derive an 'Enum' instance for that :-)

what do you hope to gain from making your flags type an instance of the
Enum class?

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Custom Enum instance with non-consecutive indices

2012-11-17 Thread Nicolas Trangez
On Sat, 2012-11-17 at 16:52 +0200, Roman Cheplyaka wrote:
> 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. 

Sure, but that kind-of defeats the purpose... fromEnum/toEnum would then
return some nonsensical integer value.

Nicolas


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Custom Enum instance with non-consecutive indices

2012-11-17 Thread Roman Cheplyaka
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  [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
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe