bbc04ecd6833e6ebd9048f21c98dcb0fc3d9d790
[packages/base.git] / Control / Monad / Zip.hs
1 {-# LANGUAGE Safe #-}
2 -----------------------------------------------------------------------------
3 -- |
4 -- Module : Control.Monad.Zip
5 -- Copyright : (c) Nils Schweinsberg 2011,
6 -- (c) George Giorgidze 2011
7 -- (c) University Tuebingen 2011
8 -- License : BSD-style (see the file libraries/base/LICENSE)
9 -- Maintainer : libraries@haskell.org
10 -- Stability : experimental
11 -- Portability : portable
12 --
13 -- Monadic zipping (used for monad comprehensions)
14 --
15 -----------------------------------------------------------------------------
16
17 module Control.Monad.Zip where
18
19 import Prelude
20 import Control.Monad (liftM)
21
22 -- | `MonadZip` type class. Minimal definition: `mzip` or `mzipWith`
23 --
24 -- Instances should satisfy the laws:
25 --
26 -- * Naturality :
27 --
28 -- > liftM (f *** g) (mzip ma mb) = mzip (liftM f ma) (liftM g mb)
29 --
30 -- * Information Preservation:
31 --
32 -- > liftM (const ()) ma = liftM (const ()) mb
33 -- > ==>
34 -- > munzip (mzip ma mb) = (ma, mb)
35 --
36 class Monad m => MonadZip m where
37
38 mzip :: m a -> m b -> m (a,b)
39 mzip = mzipWith (,)
40
41 mzipWith :: (a -> b -> c) -> m a -> m b -> m c
42 mzipWith f ma mb = liftM (uncurry f) (mzip ma mb)
43
44 munzip :: m (a,b) -> (m a, m b)
45 munzip mab = (liftM fst mab, liftM snd mab)
46 -- munzip is a member of the class because sometimes
47 -- you can implement it more efficiently than the
48 -- above default code. See Trac #4370 comment by giorgidze
49
50 instance MonadZip [] where
51 mzip = zip
52 mzipWith = zipWith
53 munzip = unzip