[Haskell-cafe] Having trouble with instance context

Kurt Stutsman kstutsman at gmail.com
Wed Feb 23 16:40:09 CET 2011


Daniel Fischer wrote:
> No, it's not. The language report says an instance head must have the form
>
> (tyCon a1 ... an),
>
> where tyCon is a type constructor and a1 ... an are *distinct* type 
> variables (appropriate in number so that the head has the correct kind).
>
> In instance (Enum e) => Test e where ..., the tyCon is not present.
>
> Since this is too restrictive for many cases, most implementations have 
> extensions allowing more liberal instance declarations (omitting the tyCon 
> part, allowing repeated type variables, ...).
>
> Note however, that the above instance means "all types are instances of 
> Test, and using a Test method on a type which doesn't belong to Enum is a 
> static error" in GHC [because the instance selection in GHC doesn't take 
> the part before the '=>' into account, so it sees 'instance Test e where'].
> If you want to declare any other instances of Test, you need to enable 
> OverlappingInstances, which is a whole 'nother can of worms.
>   
Excellent! That was just the kind of information I was looking for. Thanks.


Going back to my original problem then, I am encoding and decoding from 
a file that contains many bitsets. In my Haskell code, I am using 
Data.BitSet in conjunction with Enums I am creating for each kind of 
bitset. I thought the syntax I was using before would be perfect for 
using the same code to transcode between the bitmask integer and the 
internal representation. Test is actually a kind of Serializable class. 
I don't want to restrict it to only working with Enums, which is what 
your OverlappingInstances seems to address. Is there a better way for 
doing what I am trying to do?

Example:

import Data.BitSet

data GroupA = A1 | A2 | A3 deriving (Enum, Show)

data GroupB = B1 | B2  deriving (Enum, Show)

class Serializable t where
    get :: String -> t
    put :: t -> String

instance Enum e => Serializable e where
    get mask = {- convert mask to Int and then to a BitSet -}
    put bitset = {- convert BitSet to Int and then to String -}


Thanks,
Kurt





More information about the Haskell-Cafe mailing list