Simon says,
Here are the two proposals I suggested in
http://research.microsoft.com/Users/simonpj
> 1.Fix up the current version.
> use MonadZero for do expressions with *irrefutable* patterns
> (instead of *unfailable* patterns as now)
> 2.Nuke MonadZero altogether.
> add mfail :: m a to Monad instead
Sorry, I don't understand option 2, can you please explain?
Simon also says,
But (1) really sticks in my craw. How can we explain this:
f :: Monad m => m (a,b) -> m a
f m1 = do { x <- m1; return (fst x) }
g :: MonadZero m => m (a,b) -> m a
g m1 = do { (a,b) <- m1; return a }
h :: Monad m => m (a,b) -> m a
h m1 = do { ~(a,b) <- m1; return a }
... the type differences between g and f,h are really hard to justify.
Yes. But these subtle differences exist independent of MonadZero.
f x = [fst x]
g (a,b) = [a]
h ~(a,b) = [a]
Here it turns out f and h are equivalent and g differs, just as above.
All that differs with MonadZero is that the type is affected, as well
as the semantics. Eric and others point out that this may be a good
thing: better to find out about the difference at compile-time than
at run-time.
I want to make a different plea: keep the language design consistent!
Yes, the difference between f, g, h is a wart, but let's have one wart
repeated, rather than two different warts.
-- P