
This is funny. When I got no immediate reaction from you, I started implementing it myself. I ended up with something similar. It has less features but is also a lot simpler. This is the interface:
initGlobal :: Typeable a => a -> IO () getGlobal :: Typeable a => IO a
Your implementation is probably much simpler than mine because you don't implement withEmptyDict. I'm really quite keen about withEmptyDict, because one of the MAJOR conceptual problems I have with unsafePerformIO global variables is that you only get one universe, corresponding to the Haskell program. There shouldn't really be a single "the Haskell program" anyway; imagine something like GHC or an operating system written in Haskell which run sub-systems which require their own global variables. Or imagine a program split between lots of processors where, for efficiency reasons, you don't want everyone to have to refer to the same set of global variables.o
Storing (TypeRep,Dynamic) pairs is redundant, since Dynamics already contain their own TypeRep (that is how they are made to work).
It is, but I'm not sure if it can be avoided without using stuff not in the standard libraries.
I also use a list for the dictionary; and I share your view about TypeRep badly needing an Ord instance (probably trivial to provide but I could be wrong).
Even better would be a hashable integer. TypeRep actually is implemented internally on GHC using a hashcons'd unique integer, so exposing it should be trivial ...