
Hello glasgow-haskell-users, i've rather complicated class structure: class BufferData a where instance (FastBufferData a) => BufferData a where class FastBufferData a where instance (Storable a) => FastBufferData a where of course, it's compiled with -fallow-undecidable-instances -fallow-overlapping-instances -fallow-incoherent-instances BufferData class includes procedure `write`: 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: writeAll :: (BufferData a) => RecvBuf -> SendBuf -> Cleanup -> a -> IO () the same problems raised many times when i switched from 6.6.1 to 6.8.2 - lots of procedures need to add signatures because by default 6.8.2 decided that they are restricted to Storable does GHC developers interested in minimal test case for this problem? -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

| 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? Simon
participants (2)
-
Bulat Ziganshin
-
Simon Peyton-Jones