(original) (raw)

{-# LANGUAGE Safe #-} {-# LANGUAGE TypeOperators #-}


-- 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