
On 11/07/2011 15:25, Gábor Lehel wrote:
2011/7/11 Simon Marlow
: On 08/07/2011 17:36, Gábor Lehel wrote:
2011/7/7 Simon Marlow
: Yes, it's implementation-defined but non-varying. I know some people have objected to these things being outside the IO monad before, but there is already plenty of precedent (System.Info.os, size of Int, isIEEE...).
However, if we take it out of IO then it may limit the possible implementations. Would the previous implementation, in which keys were assigned at runtime, still be valid? It is still implementation-defined and non-varying, but only over a single run.
That's the question. It's in IO now because, while the keys don't vary over a single run, they do vary between them. Presumably the new version should be 'pure' if and only if that's no longer true. The upsides (of not being in IO) are obvious, but unfortunately I don't know much at all about the potential downsides in terms of limiting implementations.
After talking with Simon Peyton Jones about this, I decided to deprecate typeRepKey and add Ord instances to TypeRep and TyCon. Given that typeRepKey isn't returning an Int any more, it isn't adding anything over a direct Ord instance on TypeRep (we didn't do this before because the Ord instance would vary from run to run). So you can now make a Map with TypeRep as the key, however to do this efficiently you probably want to use a hash map, and make TypeRep Hashable (easy, just take a chunk of the fingerprint). Cheers, Simon
Albeit, the use case I had in mind was using Template Haskell to construct a case statement over the literal Int values of the keys as determined at compile time (hopefully compiling down to something like a C switch statement), and I'm not sure if that's going to work if the keys are no longer Ints. (That it wouldn't compile down to a switch statement is one thing, but I'm not sure if the code would literally be possible to write. Maybe it'd need a Lift instance?) Anyway, I don't think it would hurt to take it out of IO if given the opportunity, either way.
The keys are 128-bit hashes, so it might still be possible to do something like this, but you would need access to the internal representations. I'm planning to expose these via Data.Typeable.Internal (no guarantees about stability of this API, however).
I was going to suggest that a Lift instance could be provided in Language.Haskell.TH.Syntax, but I see now that there's quite a few types which could have an instance and don't, so that probably belongs in a separate proposal. Just having the internals available will hopefully be 'good enough' for the use case I mentioned (which itself is not that important, just a nice optimization).
Cheers, Simon