On Fri, 26 Nov 2004, George Russell wrote: > Ian Stark wrote (snipped): > > Way back in this thread, Koen Claessen mentioned the idea of a commutative > > version of the IO monad for handling things with identity. That doesn't > quite > > do it, but I have a refinement that might. The thing is to focus on IO > > computations that are: > > > > a) central -- their effect commutes with every other IO action > > b) affine -- their effect is not directly observable, and can be > discarded. > > Unfortunately I have a number of examples where I use global variables with > initialisation actions which cannot conceivably be proven to be central & > affine > by the compiler. For example, where I want to call up an external program > (such > as wish) which I will later use for doing graphics.
This indeed can't be proved central+affine, because it isn't. So instead, choose one of the following: 1 (Good) Indirection: declare gc <- newIORef None; so that gc is a global variable holding a (Maybe GraphicsContext). Initialise the contents in your main IO action; and then pull out the value any time you need to look at it. Yes, you need to explicitly initialise it; but you don't need then to pass the initialized handle all around your code. The painful plumbing goes away. 2 (Neutral) As above, but write getGC :: IO GraphicsContext that looks in gc, and if there is None then calls out to wish, or whatever, to initialise it first. Sound, but getGC then hides some wildly varying behaviour. 3 (Evil) Give in to the dark side. Have unsafeIOtoACIO, write a declaration using it, and hope that your compiler does the easy thing and executes all declarations at the start of the program. In fact not much worse than (2); only now the possible effect points have leapt from all uses of gc to all uses of IO. > The Haskell libraries would run into a similar problem when they tried to > open stdin/stdout/stderr. But they don't open them, right? The whole point of stdin/stdout/stderr being fixed integers is that these handles are already opened when the program starts. > Or indeed when they tried to implement RandomGen, which I presume is > going to want to get at the system clock to seed the random number > generator. Yes, the system StdGen really does have to get initialised. But the presumed readRandomNumberFromSystem() is ACIO if it's random (OK, so if it's implemented by opening /dev/random, then this would have to be wrapped in assertIOisACIO). -- Ian Stark http://www.ed.ac.uk/~stark LFCS, School of Informatics, The University of Edinburgh, Scotland _______________________________________________ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
