
Udo Stenzel wrote:
Gracjan Polak wrote:
iorefset :: Ord a => IORef(Map.Map a a) iorefset = unsafePerformIO $ do newIORef $ Map.empty
I could have as many dictionaries as there are types. The problem is I get one dictionary for each object which defeats the idea.
I believe the (Ord a) constraint acts like a function argument. Therefore iorefset is no CAF, cannot be memoized itself and you get one dictionary per invocation. On the other hand, that is what is to be expected when playing games with unsafePerformIO.
Seems you are right. Monomorphic type works, polymorphic doesn't. But it probably is not in any way guaranteed to stay like this in future.
You might get it working by giving iorefset a monomorphic type or by specializing it for the type(s) you are using it at. Don't forget the NOINLINE pragma. I wouldn't do it this way, though. If you're parsing, chances are that your code is monadic anyway. Put a StateT over the parser monad and everything works without black magic. Even better, if you're using parsec you can just put the Map in the user state.
This will create intern-per-parse, which isn't bad and has it's advantages, but I wanted to do something global. Anyway it was interesting experiment :)
Udo.
-- Gracjan