diff options
author | Nathan Collins <conathan@galois.com> | 2017-12-09 18:59:05 -0800 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2018-01-02 16:28:09 -0500 |
commit | 4887c3086149a15a1e16c765682debcfbb9de145 (patch) | |
tree | ff132212cb53435fa470837fb83ba6a6894de4af /libraries | |
parent | a67c264201a5d73d3624a73359f36adfaf6ec33c (diff) | |
download | haskell-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.hs | 32 |
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' |