summaryrefslogtreecommitdiff
path: root/libraries
diff options
context:
space:
mode:
authorNathan Collins <conathan@galois.com>2017-12-09 18:59:05 -0800
committerBen Gamari <ben@smart-cactus.org>2018-01-02 16:28:09 -0500
commit4887c3086149a15a1e16c765682debcfbb9de145 (patch)
treeff132212cb53435fa470837fb83ba6a6894de4af /libraries
parenta67c264201a5d73d3624a73359f36adfaf6ec33c (diff)
downloadhaskell-4887c3086149a15a1e16c765682debcfbb9de145.tar.gz
Improve Control.Monad docs
Summary: * Reformat Control.Monad.mfilter docs The formatting was bad, with everything running together, and a paranthesis was missing. Now the examples and relation between `filter` and `mfilter` are typeset as code blocks instead of inline. * Add example to Control.Monad.join docs The example is using `join . atomically` to run IO actions computed by STM transactions. I couldn't figure out how to link to the STM docs in `Control.Monad.STM`, because that module comes from the `stm` package, not from `base`, even though `stm` is also part of the GHC source tree. So, instead I linked to the STM docs in `GHC.Conc`, which seems inferior to linking to `Control.Monad.STM`, but better than having no links at all. * Add example to Control.Monad.forever docs The example is a simple TCP echo server. To make the uses of `forever` stand out in the example code, I only link to the non-`forever` functions (e.g. `forkFinally`) in the import lists. Reviewers: bgamari, hvr Subscribers: rwbarton, thomie, carter Differential Revision: https://phabricator.haskell.org/D4259
Diffstat (limited to 'libraries')
-rw-r--r--libraries/base/Control/Monad.hs32
1 files changed, 31 insertions, 1 deletions
diff --git a/libraries/base/Control/Monad.hs b/libraries/base/Control/Monad.hs
index 8d664e6210..d9bfdebd54 100644
--- a/libraries/base/Control/Monad.hs
+++ b/libraries/base/Control/Monad.hs
@@ -152,7 +152,37 @@ f >=> g = \x -> f x >>= g
(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> (a -> m c)
(<=<) = flip (>=>)
--- | @'forever' act@ repeats the action infinitely.
+-- | Repeat an action indefinitely.
+--
+-- ==== __Examples__
+--
+-- Simple network servers can be created by writing a function to
+-- handle a single client connection and then using 'forever' to
+-- accept client connections and fork threads to handle them.
+--
+-- For example, here is a [TCP echo
+-- server](https://en.wikipedia.org/wiki/Echo_Protocol) implemented
+-- with 'forever':
+--
+-- @
+-- import "Control.Concurrent" ( 'Control.Concurrent.forkFinally' )
+-- import "Control.Monad" ( 'forever' )
+-- import Network ( PortID(..), accept, listenOn )
+-- import "System.IO" ( 'System.IO.hClose', 'System.IO.hGetLine', 'System.IO.hPutStrLn' )
+--
+-- main :: IO ()
+-- main = do
+-- sock <- listenOn (PortNumber 7)
+-- 'forever' $ do
+-- (handle, _, _) <- accept sock
+-- echo handle \`forkFinally\` const (hClose handle)
+-- where
+-- echo handle = 'forever' $
+-- hGetLine handle >>= hPutStrLn handle
+-- @
+--
+-- The @Network@ module is provided by the [network
+-- package](https://hackage.haskell.org/package/network).
forever :: (Applicative f) => f a -> f b
{-# INLINE forever #-}
forever a = let a' = a *> a' in a'