[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.

HTH!

--
Felipe.


More information about the Beginners mailing list