On Sun, Feb 13, 2005 at 01:31:56PM -0500, David Roundy wrote: > On Sun, Feb 13, 2005 at 04:57:46PM +0100, Remi Turk wrote: > > According to http://www.haskell.org/hawiki/MonadPlus (see also > > the recent thread about MonadPlus) a MonadPlus instance > > should obey m >> mzero === mzero, which IO doesn't. IOW, the > > MonadPlus instance for IO (defined in Control.Monad.Error) > > probably shouldn't be there. > > True. In the IO monad there are side effects that don't get "erased" when > a later action raises an exception as that law would suggest. But any > IO-like monad that I'm likely to implement will have the same discrepancy, > and in any IO code that catches "enough" exceptions to be bug-free will be > immune to this issue. > > Basically, the issue is that > > do { writeFile "foo" "bar"; writeFile "bar" "foo" } `catch` > \_ -> putStr "Couldn't create file\m" > > may reach the putStr with or without the file "foo" existing, and there's > no way to know whether or not it was created. But that just means the code > was written sloppily--that is, if the existence of that foo file is > important. > > In my uses of MonadPlus, I'd have other schemes essentially immitating IO, > so they'd duplicate this behavior (later errors don't undo earlier > actions), and well-written functions would depend on that.
But what if `instance MonadPlus IO' disappears from the libraries some day? (which it should, IMO) > It might be interesting to write a "backtracking" IO-like monad which > obeyed m >> mzero === mzero. I imagine you could do it for something like > an ACID database, if you define === as meaning "has the same final result > on the database", which of course would only be useful if the database had > sufficient locking that it couldn't have been read between the original m > and the later mzero. You might be interested in the recent STM monad then (Control.Concurrent.STM in GHC-6.4): `T' for Transactional. However, though it supports both MonadPlus and exceptions, it doesn't use MonadPlus for exceptions: It's used for blocking/retrying a thread/transaction. I never used it, so I'm not sure whether it makes any sense, but wouldn't MonadError be a better candidate class to base it upon? Greetings, Remi -- Nobody can be exactly like me. Even I have trouble doing it. _______________________________________________ Haskell-Cafe mailing list [email protected] http://www.haskell.org/mailman/listinfo/haskell-cafe
