[Haskell-beginners] Easier alternatives to existential types?

Felipe Lessa felipe.lessa at gmail.com
Wed Nov 25 22:41:40 EST 2009

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.



More information about the Beginners mailing list