25 Aug 01:08
Top Level <-
From: Ashley Yakeley <ashley <at> semantic.org>
Subject: Top Level <-
Newsgroups: gmane.comp.lang.haskell.general
Date: 2008-08-24 23:12:18 GMT
Subject: Top Level <-
Newsgroups: gmane.comp.lang.haskell.general
Date: 2008-08-24 23:12:18 GMT
Is there any interest in implementing a top level "<-" to run monadic code? Currently this sort of thing is done with unsafePerformIO and switching off inlining with some pragma. Indeed, the 'atomically' haddock actually advises doing this to declare top-level TVars. The same trick is used in the source of Data.Unique and System.Random. This is bad Haskell. To avoid observation of effects, etc., we would need a new monad rather than IO. There would be equivalents of IO functions such as these: newIORef newMVar newTVarIO newUnique I can think of two uses: 1. Global mutable state. For instance, here's the count variable for Data.Unique rewritten: uniqSource :: MVar Integer uniqSource <- newMVarTL 0 Isn't that much nicer? <http://haskell.org/haskellwiki/Top_level_mutable_state> 2. Solving the expression problem using open witnesses, a recent hobby-horse of mine. For instance, here's a simple scheme for extensible exceptions using top-level "<-":(Continue reading)
I implemented my own ACIO monad a while ago (which is of course quite
useless without top level <- bindings) and it turned out that there
was quite a lot that could go in here.
The only problem seemed to be that some things that seemed perfectly
reasonable to create via ACIO had *IO* finalisers associated with them,
which didn't feel right to me. But if you think about how finalisers
get run I'm inclined to think we should insist that they are ACIO too.
Regards
--
Adrian Hey
I tried it anyway and doesn't seem to work, but that ain't so surprising
as Handles aren't Nums.
What needs explaining IMO is that we appear to have "global" Handles
exported at the top level from System.IO, but no way for users to write
their own modules that do the same for nonStdout, or even to implement
getNonStdout. I think that's pretty weird and inconsistent.
But perhaps you could show me how to do it with some real Haskell