diff --git a/docs/a-fistful-of-monads.html b/docs/a-fistful-of-monads.html index 497fddd..478941a 100644 --- a/docs/a-fistful-of-monads.html +++ b/docs/a-fistful-of-monads.html @@ -381,29 +381,22 @@
-class Monad m where +class Applicative m => Monad m where return :: a -> m a + return = pure (>>=) :: m a -> (a -> m b) -> m b (>>) :: m a -> m b -> m b x >> y = x >>= \_ -> y - - fail :: String -> m a - fail msg = error msg
-Let's start with the first line. It says class Monad m where. -But wait, didn't we say that monads are just beefed up applicative functors? Shouldn't -there be a class constraint in there along the lines of class (Applicative m) = > Monad m where so that a type -has to be an applicative functor first before it can be made a monad? Well, -there should, but when Haskell was made, it hadn't occured to people that -applicative functors are a good fit for Haskell so they weren't in there. But -rest assured, every monad is an applicative functor, even if the Monad class declaration doesn't say so. +Let's start with the first line. It says +class (Applicative m) = > Monad m where which means +that if we want to create an instance of Monad for some time, we must have an +instance of Applicative for that type.
@@ -445,11 +438,6 @@
-The final function of the Monad type class is -fail. We never use it explicitly in our code. Instead, it's used by Haskell to enable failure in a special syntactic construct for monads that we'll meet later. We don't need to concern ourselves with fail too much for now. -
-Now that we know what the Monad type class looks like, let's take a look at how Maybe is an instance @@ -458,17 +446,15 @@
instance Monad Maybe where - return x = Just x Nothing >>= f = Nothing Just x >>= f = f x - fail _ = Nothing
-return is the same as pure, so that one's a no-brainer. We do what we did in the -Applicative type class and wrap it in a Just. +Both return and (>>) have default +implementations, so we omit them in instances. return +is the same as pure, it wraps a value in +Just.
@@ -1274,25 +1260,26 @@
-fail :: (Monad m) => String -> m a -fail msg = error msg +class Monad m => MonadFail m where + fail :: String -> m a
-So by default it does make our program crash, but monads that incorporate a +Monads that incorporate a context of possible failure (like Maybe) usually implement it on their own. For Maybe, its implemented like so:
-fail _ = Nothing +instance MonadFail Maybe where + fail _ = Nothing
@@ -1368,9 +1355,7 @@
instance Monad [] where - return x = [x] xs >>= f = concat (map f xs) - fail _ = []
@@ -1563,41 +1548,41 @@
-class Monad m => MonadPlus m where - mzero :: m a - mplus :: m a -> m a -> m a +class Applicative f => Alternative f where + empty :: f a + (<|>) :: f a -> f a -> f a
-mzero is synonymous to mempty +empty is synonymous to mempty from the Monoid type class and mplus corresponds to mappend. +class="fixed">(<|>) corresponds to mappend. Because lists are monoids as well as monads, they can be made an instance of this type class:
-instance MonadPlus [] where - mzero = [] - mplus = (++) +instance Alternative [] where + empty = [] + (<>) = (++)
-For lists mzero represents a non-deterministic +For lists empty represents a non-deterministic computation that has no results at all — a failed computation. mplus joins two non-deterministic values into one. The +class="fixed">(<|>) joins two non-deterministic values into one. The guard function is defined like this:
-guard :: (MonadPlus m) => Bool -> m () -guard True = return () -guard False = mzero +guard :: (Alternative m) => Bool -> m () +guard True = pure () +guard False = empty