
On Thu, Nov 26, 2009 at 06:37:57AM +0400, Emile Melnicov wrote:
I'm trying to write RIFF parser and can't decide what to do with "container" type. "Container" chunk should hold a header (two Word32's), a "type" (Word32 like "WAVE" etc) and a "list" of other chunks. Of course lists can't be used because we have far more than one chunk types. What can I do with this?
data Header = H {fieldAbc :: Word32 ,filedXyz :: Word32} data Type = AU | WAVE | ... data ContainerChunk = Chunk Header Type [ContainerChunk] Well, yes, I know that almost certanly that was not what you were thinking when you wrote the question. The code above is how I interpreted your question. I'm writing it so that you can clarify the question if the others don't understand as well. Maybe, something like this? data WaveChunk = Wave {...} data AuChunk = Au {...} data Container = ...any chunk above... doSomethingWillAllThoseFiles :: [Container] -> IO () You may want to keep it simple and just use data Container = TypeWave WaveChunk | TypeAu AuChunk If you really want existentials, though, I'd recommend using GADT syntax as in class Chunk c where ... instance Chunk WaveChunk where ... instance Chunk AuChunk where ... data Container where AudioChunk :: Chunk c => c -> Container x,y :: Container x = AudioChunk (Wave {...}) y = AudioChunk (Au {...}) f :: Chunk c => c -> IO () f = ... g :: Container -> IO () g (AudioChunk c) = f c -- pattern match brings (Chunk c) into context. Note that 'c' above doesn't appear in the type of the Container. This roughly means that it will be existentially qualified. HTH! -- Felipe.