... | ... | @@ -8,19 +8,22 @@ This page contains some notes and ideas that predate the official **[MonadFail]( |
|
|
## The Basic Idea
|
|
|
|
|
|
|
|
|
|
|
|
The basic idea is to split the `Monad` class into
|
|
|
|
|
|
|
|
|
```
|
|
|
classApplicative m =>Monad m where(>>=):: m a ->(a -> m b)-> m b
|
|
|
class Applicative m => Monad m where
|
|
|
(>>=) :: m a -> (a -> m b) -> m b
|
|
|
|
|
|
(>>):: m a -> m b -> m b
|
|
|
m >> k = m >>=\_-> k
|
|
|
(>>) :: m a -> m b -> m b
|
|
|
m >> k = m >>= \_ -> k
|
|
|
|
|
|
return :: a -> m a -- still in Monad for historic reasons
|
|
|
return = pure
|
|
|
|
|
|
classMonad m =>MonadFail m where
|
|
|
fail ::String-> m a
|
|
|
class Monad m => MonadFail m where
|
|
|
fail :: String -> m a
|
|
|
```
|
|
|
|
|
|
|
... | ... | @@ -30,11 +33,13 @@ See [ https://github.com/quchen/articles/blob/master/monad_fail.md](https://gith |
|
|
### Misc Ideas
|
|
|
|
|
|
|
|
|
|
|
|
To aid transition, we can keep `fail` in `Monad`, and start out with
|
|
|
|
|
|
|
|
|
```
|
|
|
classMonad m =>MonadFail m where
|
|
|
mfail ::String-> m a
|
|
|
class Monad m => MonadFail m where
|
|
|
mfail :: String -> m a
|
|
|
```
|
|
|
|
|
|
|
... | ... | @@ -48,37 +53,51 @@ The `MonadFail(mfail)` desugaring of `do` could then be enabled via a language p |
|
|
## History
|
|
|
|
|
|
|
|
|
In [ Haskell 1.4 (postscript)](http://haskell.org/definition/haskell-report-1.4.ps.gz)`fail` was not part of the `Monad` class. Instead there was a separate `MonadZero` class containing the `zero` operation whose purpose was to handle pattern-failures in `do`-syntax (akin to what `fail` does today). Here are the original Haskell 1.4 class definitions quoted from section "6.2.5 Monadic Classes":
|
|
|
|
|
|
In [ Haskell 1.4 (postscript)](http://haskell.org/definition/haskell-report-1.4.ps.gz) `fail` was not part of the `Monad` class. Instead there was a separate `MonadZero` class containing the `zero` operation whose purpose was to handle pattern-failures in `do`-syntax (akin to what `fail` does today). Here are the original Haskell 1.4 class definitions quoted from section "6.2.5 Monadic Classes":
|
|
|
|
|
|
|
|
|
```
|
|
|
classFunctor f where
|
|
|
map ::(a -> b)->(f a -> f b)classMonad m where(>>=):: m a ->(a -> m b)-> m b
|
|
|
(>>):: m a -> m b -> m b
|
|
|
class Functor f where
|
|
|
map :: (a -> b) -> (f a -> f b)
|
|
|
|
|
|
class Monad m where
|
|
|
(>>=) :: m a -> (a -> m b) -> m b
|
|
|
(>>) :: m a -> m b -> m b
|
|
|
return :: a -> m a
|
|
|
|
|
|
class(Monad m)=>MonadZero m where
|
|
|
class (Monad m) => MonadZero m where
|
|
|
zero :: m a
|
|
|
|
|
|
class(MonadZero m)=>MonadPlus m where(++):: m a -> m a -> m a
|
|
|
class (MonadZero m) => MonadPlus m where
|
|
|
(++) :: m a -> m a -> m a
|
|
|
```
|
|
|
|
|
|
|
|
|
However, when Haskell 98 was drafted [ issues with irrefutable patterns](http://marc.info/?l=haskell&m=66622011823641) lead to `MonadZero` being folded into the `Monad` class (but it doesn't seem to have been an unanimous nor easy decision back then).
|
|
|
|
|
|
|
|
|
|
|
|
The issue is highlighted by deconstructing a monadic action returning a single-constructor value:
|
|
|
|
|
|
|
|
|
```
|
|
|
f::Monad m => m (a,b)-> m a
|
|
|
f m1 =do{ x <- m1; return (fst x)}g::??? m => m (a,b)-> m a
|
|
|
g m1 =do{(a,_)<- m1; return a }h::Monad m => m (a,b)-> m a
|
|
|
h m1 =do{~(a,_)<- m1; return a }
|
|
|
f :: Monad m => m (a,b) -> m a
|
|
|
f m1 = do { x <- m1; return (fst x) }
|
|
|
|
|
|
g :: ??? m => m (a,b) -> m a
|
|
|
g m1 = do { (a,_) <- m1; return a }
|
|
|
|
|
|
h :: Monad m => m (a,b) -> m a
|
|
|
h m1 = do { ~(a,_) <- m1; return a }
|
|
|
```
|
|
|
|
|
|
|
|
|
Should `???` for `g` be `Monad` or `MonadZero`? The single-constructor pattern match will never fail ("unfailable"), so `zero` is never used. In fact, in Haskell 1.4 `g` would only require `Monad`, but requires the concept of \`"unfailable" pattern matches (in addition to "irrefutable" pattern matches).
|
|
|
|
|
|
|
|
|
## Related Concepts/Proposals
|
|
|
|
|
|
|
|
|
- [ MonadPlus reform proposal](https://wiki.haskell.org/MonadPlus_reform_proposal)
|
|
|
- [ApplicativeDo](applicative-do) |
|
|
\ No newline at end of file |
|
|
- [ApplicativeDo](applicative-do) |