bug in 6.8.2?

Simon Peyton-Jones simonpj at microsoft.com
Mon May 19 07:00:40 EDT 2008

| class BufferData a where
|   write :: OutStream -> a -> IO ()
| there is writeAll procedure which uses this `write` and therefore
| should be able to write any BufferData instance:
| writeAll receiveBuf sendBuf cleanup x =
|   bracket (create receiveBuf sendBuf cleanup) (closeOut)
|     (\buf -> write buf x)
| it works great in 6.6.1 but in 6.8.2 GHC infers that writeAll can
| write only Storable instances, so i was forced to add signature to
| writeAll:

Ah, well. You have
        write :: BufferData a => ...

So a call to write gives rise to the constraint (BufferData a).  Ah, but there's an instance declaration for that, so GHC simplifies it using.
  instance (FastBufferData a) => BufferData a where
Now we need (FastBufferData a). Ah, there's an instance for that too.
  instance (Storable a) => FastBufferData a where

Oh, you say, I didn't want GHC to simplify (BufferData a), because in a *call* of writeAll, I might instantiate 'a' to T, and I have a more specialised instance of (BufferData T).

Fair enough.  And indeed, GHC is *supposed* to refrain from using the (BufferData a) instance if it sees *any* more specialised instance.  UNLESS
  a) it can only "see" the (BufferData a) instance, so it doesn't know
        there are more specialised one
  b) you specify -fallow-incoherent-instances.  Which you do.
        So you get, well, incoherence.

I suspect you are being bitten by (b).  The incoherent-instance thing is the most dodgy of GHC's type-class flags.  Are you sure you want it?


More information about the Glasgow-haskell-users mailing list