
Simon Peyton-Jones wrote:
The trouble is that *any* "function" can now deliver unpredictable results. Can I rely on the fact that foo :: Int -> Int will always give the same answer given the same input. Not any more.
Yes, I see what you mean.
I think the strongest argument here is that it's like a more benign version of unsafePerformIO, whose existence also threatens foo's predictability.
I suggest you implement hashTypeable :: Typeable -> IO Int32 This would be just as useful for global variables/execution contexts as allowing a hash function which doesn't mention IO, but still preserves determinacy for foo :: Int -> Int. Determinacy for foo :: Int -> IO Int won't be preserved, but then of course you didn't have it in the first place, even with Haskell 98. If there were a Hash class (I think there should be), then it might in general be a good idea to define it by
class Hash a where hash :: a -> IO HashInt
You don't need a pure function for this after all.