You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/a-fistful-of-monads.html
+32-47Lines changed: 32 additions & 47 deletions
Original file line number
Diff line number
Diff line change
@@ -381,29 +381,22 @@ <h2>The Monad type class</h2>
381
381
</p>
382
382
383
383
<prename="code" class="haskell:hs">
384
-
class Monad m where
384
+
class Applicative m => Monad m where
385
385
return :: a -> m a
386
+
return = pure
386
387
387
388
(>>=) :: m a -> (a -> m b) -> m b
388
389
389
390
(>>) :: m a -> m b -> m b
390
391
x >> y = x >>= \_ -> y
391
-
392
-
fail :: String -> m a
393
-
fail msg = error msg
394
392
</pre>
395
393
396
394
<imgsrc="assets/images/a-fistful-of-monads/kid.png" alt="this is you on monads" class="right" width="363" height="451">
397
395
<p>
398
-
Let's start with the first line. It says <spanclass="fixed">class Monad m where</span>.
399
-
But wait, didn't we say that monads are just beefed up applicative functors? Shouldn't
400
-
there be a class constraint in there along the lines of <span
401
-
class="fixed">class (Applicative m) = > Monad m where</span> so that a type
402
-
has to be an applicative functor first before it can be made a monad? Well,
403
-
there should, but when Haskell was made, it hadn't occured to people that
404
-
applicative functors are a good fit for Haskell so they weren't in there. But
405
-
rest assured, every monad is an applicative functor, even if the <span
406
-
class="fixed">Monad</span> class declaration doesn't say so.
396
+
Let's start with the first line. It says
397
+
<spanclass="fixed">class (Applicative m) = > Monad m where</span> which means
398
+
that if we want to create an instance of Monad for some time, we must have an
399
+
instance of Applicative for that type.
407
400
</p>
408
401
409
402
<p>
@@ -445,11 +438,6 @@ <h2>The Monad type class</h2>
445
438
instances.
446
439
</p>
447
440
448
-
<p>
449
-
The final function of the <spanclass="fixed">Monad</span> type class is
450
-
<spanclass="fixed">fail</span>. 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 <spanclass="fixed">fail</span> too much for now.
451
-
</p>
452
-
453
441
<p>
454
442
Now that we know what the <spanclass="fixed">Monad</span> type class looks
455
443
like, let's take a look at how <spanclass="fixed">Maybe</span> is an instance
@@ -458,17 +446,15 @@ <h2>The Monad type class</h2>
458
446
459
447
<prename="code" class="haskell:hs">
460
448
instance Monad Maybe where
461
-
return x = Just x
462
449
Nothing >>= f = Nothing
463
450
Just x >>= f = f x
464
-
fail _ = Nothing
465
451
</pre>
466
452
467
453
<p>
468
-
<spanclass="fixed">return</span>is the same as <span
469
-
class="fixed">pure</span>, so that one's a no-brainer. We do what we did in the
470
-
<spanclass="fixed">Applicative</span> type class and wrap it in a <span
471
-
class="fixed">Just</span>.
454
+
Both <spanclass="fixed">return</span>and <spanclass="fixed">(>>)</span> have <em>default
455
+
implementations</em>, so we omit them in instances. <spanclass="fixed">return</span>
456
+
is the same as <spanclass="fixed">pure</span>, it wraps a value in
457
+
<spanclass="fixed">Just</span>.
472
458
</p>
473
459
474
460
<p>
@@ -1274,25 +1260,26 @@ <h2>do notation</h2>
1274
1260
present in <spanclass="fixed">let</span> expressions. When pattern matching
1275
1261
fails in a <spanclass="fixed">do</span> expression, the <span
1276
1262
class="fixed">fail</span> function is called. It's part of the <span
1277
-
class="fixed">Monad</span> type class and it enables failed pattern matching to
1263
+
class="fixed">MonadFail</span> type class and it enables failed pattern matching to
1278
1264
result in a failure in the context of the current monad instead of making our
1279
-
program crash. Its default implementation is this:
1265
+
program crash.
1280
1266
</p>
1281
1267
1282
1268
<prename="code" class="haskell:hs">
1283
-
fail :: (Monad m) => String -> m a
1284
-
fail msg = error msg
1269
+
class Monad m => MonadFail m where
1270
+
fail :: String -> m a
1285
1271
</pre>
1286
1272
1287
1273
<p>
1288
-
So by default it does make our program crash, but monads that incorporate a
1274
+
Monads that incorporate a
1289
1275
context of possible failure (like <spanclass="fixed">Maybe</span>) usually
1290
1276
implement it on their own. For <spanclass="fixed">Maybe</span>, its implemented
1291
1277
like so:
1292
1278
</p>
1293
1279
1294
1280
<prename="code" class="haskell:hs">
1295
-
fail _ = Nothing
1281
+
instance MonadFail Maybe where
1282
+
fail _ = Nothing
1296
1283
</pre>
1297
1284
1298
1285
<p>
@@ -1368,9 +1355,7 @@ <h2>The list monad</h2>
1368
1355
1369
1356
<prename="code" class="haskell:hs">
1370
1357
instance Monad [] where
1371
-
return x = [x]
1372
1358
xs >>= f = concat (map f xs)
1373
-
fail _ = []
1374
1359
</pre>
1375
1360
1376
1361
<p>
@@ -1563,41 +1548,41 @@ <h2>The list monad</h2>
1563
1548
class="fixed">'7'</span> is part of that string. Pretty clever. To see how
1564
1549
filtering in list comprehensions translates to the list monad, we have to check
1565
1550
out the <spanclass="fixed">guard</span> function and the <span
1566
-
class="fixed">MonadPlus</span> type class. The <spanclass="fixed">MonadPlus</span>
1567
-
type class is for monads that can also act as monoids. Here's its definition:
1551
+
class="fixed">Alternative</span> type class. The <spanclass="fixed">Alternative</span>
1552
+
type class is for Applicatives that can also act as monoids. Here's its definition:
1568
1553
</p>
1569
1554
1570
1555
<prename="code" class="haskell:hs">
1571
-
class Monad m => MonadPlus m where
1572
-
mzero :: m a
1573
-
mplus :: m a -> m a -> m a
1556
+
class Applicative f => Alternative f where
1557
+
empty :: f a
1558
+
(<|>) :: f a -> f a -> f a
1574
1559
</pre>
1575
1560
1576
1561
<p>
1577
-
<spanclass="fixed">mzero</span> is synonymous to <spanclass="fixed">mempty</span>
1562
+
<spanclass="fixed">empty</span> is synonymous to <spanclass="fixed">mempty</span>
1578
1563
from the <spanclass="fixed">Monoid</span> type class and <span
1579
-
class="fixed">mplus</span> corresponds to <spanclass="fixed">mappend</span>.
1564
+
class="fixed">(<|>)</span> corresponds to <spanclass="fixed">mappend</span>.
1580
1565
Because lists are monoids as well as monads, they can be made an instance of
1581
1566
this type class:
1582
1567
</p>
1583
1568
1584
1569
<prename="code" class="haskell:hs">
1585
-
instance MonadPlus [] where
1586
-
mzero = []
1587
-
mplus = (++)
1570
+
instance Alternative [] where
1571
+
empty = []
1572
+
(<>) = (++)
1588
1573
</pre>
1589
1574
1590
1575
<p>
1591
-
For lists <spanclass="fixed">mzero</span> represents a non-deterministic
1576
+
For lists <spanclass="fixed">empty</span> represents a non-deterministic
1592
1577
computation that has no results at all — a failed computation. <span
1593
-
class="fixed">mplus</span> joins two non-deterministic values into one. The
1578
+
class="fixed">(<|>)</span> joins two non-deterministic values into one. The
1594
1579
<spanclass="fixed">guard</span> function is defined like this:
0 commit comments