(original) (raw)
{-# LANGUAGE Safe #-} {-# LANGUAGE TypeOperators #-}
-- | -- Module : Control.Monad.Zip -- Copyright : (c) Nils Schweinsberg 2011, -- (c) George Giorgidze 2011 -- (c) University Tuebingen 2011 -- License : BSD-style (see the file libraries/base/LICENSE) -- Maintainer : libraries@haskell.org -- Stability : experimental -- Portability : portable
-- Monadic zipping (used for monad comprehensions)
module Control.Monad.Zip where
import Control.Monad (liftM, liftM2) import Data.Functor.Identity import Data.Monoid import Data.Ord ( Down(..) ) import Data.Proxy import qualified Data.List.NonEmpty as NE import GHC.Generics
-- | MonadZip
type class. Minimal definition: mzip
or mzipWith
-- Instances should satisfy the laws:
-- * Naturality :
-- > liftM (f *** g) (mzip ma mb) = mzip (liftM f ma) (liftM g mb)
-- * Information Preservation:
-- > liftM (const ()) ma = liftM (const ()) mb -- > ==> -- > munzip (mzip ma mb) = (ma, mb)
class Monad m => MonadZip m where {-# MINIMAL mzip | mzipWith #-}
[mzip](Control.Monad.Zip.html#mzip) :: [m](#local-6989586621679420051) [a](#local-6989586621679420052) -> [m](#local-6989586621679420051) [b](#local-6989586621679420053) -> [m](#local-6989586621679420051) ([a](#local-6989586621679420052),[b](#local-6989586621679420053))
[mzip](Control.Monad.Zip.html#mzip) = [mzipWith](Control.Monad.Zip.html#mzipWith) (,)
[mzipWith](Control.Monad.Zip.html#mzipWith) :: ([a](#local-6989586621679420054) -> [b](#local-6989586621679420055) -> [c](#local-6989586621679420056)) -> [m](#local-6989586621679420051) [a](#local-6989586621679420054) -> [m](#local-6989586621679420051) [b](#local-6989586621679420055) -> [m](#local-6989586621679420051) [c](#local-6989586621679420056)
[mzipWith](Control.Monad.Zip.html#mzipWith) [f](#local-6989586621679420059) [ma](#local-6989586621679420060) [mb](#local-6989586621679420061) = [liftM](GHC.Base.html#liftM) ([uncurry](Data.Tuple.html#uncurry) [f](#local-6989586621679420059)) ([mzip](Control.Monad.Zip.html#mzip) [ma](#local-6989586621679420060) [mb](#local-6989586621679420061))
[munzip](Control.Monad.Zip.html#munzip) :: [m](#local-6989586621679420051) ([a](#local-6989586621679420057),[b](#local-6989586621679420058)) -> ([m](#local-6989586621679420051) [a](#local-6989586621679420057), [m](#local-6989586621679420051) [b](#local-6989586621679420058))
[munzip](Control.Monad.Zip.html#munzip) [mab](#local-6989586621679420062) = ([liftM](GHC.Base.html#liftM) [fst](Data.Tuple.html#fst) [mab](#local-6989586621679420062), [liftM](GHC.Base.html#liftM) [snd](Data.Tuple.html#snd) [mab](#local-6989586621679420062))
-- munzip is a member of the class because sometimes
-- you can implement it more efficiently than the
-- above default code. See Trac #4370 comment by giorgidze
-- | @since 4.3.1.0 instance MonadZip [] where mzip = zip mzipWith = zipWith munzip = unzip
-- | @since 4.9.0.0 instance MonadZip NE.NonEmpty where mzip = NE.zip mzipWith = NE.zipWith munzip = NE.unzip
-- | @since 4.8.0.0 instance MonadZip Identity where mzipWith = liftM2 munzip (Identity (a, b)) = (Identity a, Identity b)
-- | @since 4.8.0.0 instance MonadZip Dual where -- Cannot use coerce, it's unsafe mzipWith = liftM2
-- | @since 4.8.0.0 instance MonadZip Sum where mzipWith = liftM2
-- | @since 4.8.0.0 instance MonadZip Product where mzipWith = liftM2
-- | @since 4.8.0.0 instance MonadZip Maybe where mzipWith = liftM2
-- | @since 4.8.0.0 instance MonadZip First where mzipWith = liftM2
-- | @since 4.8.0.0 instance MonadZip Last where mzipWith = liftM2
-- | @since 4.8.0.0 instance MonadZip f => MonadZip (Alt f) where mzipWith f (Alt ma) (Alt mb) = Alt (mzipWith f ma mb)
-- | @since 4.9.0.0 instance MonadZip Proxy where mzipWith _ _ _ = Proxy
-- Instances for GHC.Generics -- | @since 4.9.0.0 instance MonadZip U1 where mzipWith _ _ _ = U1
-- | @since 4.9.0.0 instance MonadZip Par1 where mzipWith = liftM2
-- | @since 4.9.0.0 instance MonadZip f => MonadZip (Rec1 f) where mzipWith f (Rec1 fa) (Rec1 fb) = Rec1 (mzipWith f fa fb)
-- | @since 4.9.0.0 instance MonadZip f => MonadZip (M1 i c f) where mzipWith f (M1 fa) (M1 fb) = M1 (mzipWith f fa fb)
-- | @since 4.9.0.0 instance (MonadZip f, MonadZip g) => MonadZip (f :*: g) where mzipWith f (x1 :*: y1) (x2 :*: y2) = mzipWith f x1 x2 :*: mzipWith f y1 y2
-- instances for Data.Ord
-- | @since 4.12.0.0 instance MonadZip Down where mzipWith = liftM2