
On Thursday 28 August 2008 2:28:35 pm David Roundy wrote:
On Thu, Aug 28, 2008 at 01:17:29PM -0400, Dan Doel wrote:
On Thursday 28 August 2008 12:26:27 pm Adrian Hey wrote:
As I've pointed out several times already you can find simple examples in the standard haskell libs. So far nobody has accepted my challenge to re-implement any of these "competantly" (I.E. avoiding the use of global variables).
Why don't you try it with Data.Unique and find out :-)
Here's a first pass:
-- snip --
{-# LANGUAGE Rank2Types, GeneralizedNewtypeDeriving #-}
module Unique where
If you want this to actually provide any guarantees, of course, you'll have to provide an export list.
Yes, quite right. I didn't spend a lot of time on it. I believe U and unU would need to be hidden to prevent people from doing bad things. Another problem I thought of after the fact is that if you need to extend the IO monad in any other similar way, you're out of luck. However, I think you can modify things to something like: newtype UT r m a = UT { unUT :: ReaderT (MVar Integer) m a } ... runUT :: MonadIO m => (forall r. UT r m a) -> m a runUT m = liftIO (newMVar 0) >>= runReaderT (unUT m) ... Or if you want to get really fancy, maybe you could invent an entire new sectioned, composable IO monad like Datatypes a la Carte. But that's a fair amount more work. Cheers. -- Dan