You can create a readLayer function that returns something like this:
data OneLayer = forall a. Layer a => OneLayer a
Such that we get:
-- Read next layer
readLayer :: Handle -> IO OneLayerStill, I feel that an ADT that combines all types is better as it fits the problem perfectly. Every time you add a new layer it will generate warnings for missing pattern matches.
Regards,
Sumit