[Haskell-cafe] What is MonadPlus good for?
Remi Turk
rturk at science.uva.nl
Sun Feb 13 14:06:36 EST 2005
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.
More information about the Haskell-Cafe
mailing list