monad comprehensions: Group and Zip monad
[ghc-base.git] / Control / Monad / Zip.hs
1 -----------------------------------------------------------------------------
2 -- |
3 -- Module      :  Control.Monad.Zip
4 -- Copyright   :  (c) Nils Schweinsberg 2011,
5 --                (c) University Tuebingen 2011
6 -- License     :  BSD-style (see the file libraries/base/LICENSE)
7 -- Maintainer  :  libraries@haskell.org
8 -- Stability   :  experimental
9 -- Portability :  portable
10 --
11 -- Monadic zipping (used for monad comprehensions)
12 --
13 -----------------------------------------------------------------------------
14
15 module Control.Monad.Zip where
16
17 import Prelude
18 import Control.Monad (liftM)
19
20 -- | `MonadZip` type class. Minimal definition: `mzip` or `mzipWith`
21 --
22 -- Instances should satisfy the laws:
23 --
24 -- * Naturality :
25 --
26 --   > liftM (f *** g) (mzip ma mb) = mzip (liftM f ma) (liftM g mb)
27 --
28 -- * Information Preservation:
29 --
30 --   > liftM (const ()) ma = liftM (const ()) mb
31 --   > ==>
32 --   > munzip (mzip ma mb) = (ma, mb)
33 --
34 class Monad m => MonadZip m where
35
36     mzip :: m a -> m b -> m (a,b)
37     mzip = mzipWith (,)
38
39     mzipWith :: (a -> b -> c) -> m a -> m b -> m c
40     mzipWith f ma mb = liftM (uncurry f) (mzip ma mb)
41
42 instance MonadZip [] where
43     mzip = zip
44
45 munzip :: MonadZip m => m (a,b) -> (m a, m b)
46 munzip mab = (liftM fst mab, liftM snd mab)