{-# LANGUAGE Safe, MultiParamTypeClasses, FunctionalDependencies #-}

{- |
    Module      :  SDP.ZipM
    Copyright   :  (c) Andrey Mulik 2021
    License     :  BSD-style
    Maintainer  :  work.a.mulik@gmail.com
    Portability :  portable
    
    "SDP.ZipM" provides 'ZipM' - class of monadic zips.
-}
module SDP.ZipM
(
  -- * Export
  module SDP.Zip,
  
  -- * ZipM
  ZipM (..)
)
where

import Prelude ()
import SDP.SafePrelude
import SDP.Zip

default ()

--------------------------------------------------------------------------------

-- | 'ZipM' is monadic version of 'SDP.Zip.Zip'.
class (Monad m) => ZipM m z | z -> m
  where
    {-# MINIMAL zipWithM #-}
    
    -- | Monadic 'zip'.
    zipM  :: z a -> z b -> m (z (a, b))
    zipM  =  (a -> b -> (a, b)) -> z a -> z b -> m (z (a, b))
forall (m :: * -> *) (z :: * -> *) a b r.
ZipM m z =>
(a -> b -> r) -> z a -> z b -> m (z r)
mzipWith  (,)
    
    -- | Monadic 'zip3'.
    zipM3 :: z a -> z b -> z c -> m (z (a, b, c))
    zipM3 =  (a -> b -> c -> (a, b, c)) -> z a -> z b -> z c -> m (z (a, b, c))
forall (m :: * -> *) (z :: * -> *) a b c r.
ZipM m z =>
(a -> b -> c -> r) -> z a -> z b -> z c -> m (z r)
mzipWith3 (,,)
    
    -- | Monadic 'zip4'.
    zipM4 :: z a -> z b -> z c -> z d -> m (z (a, b, c, d))
    zipM4 =  (a -> b -> c -> d -> (a, b, c, d))
-> z a -> z b -> z c -> z d -> m (z (a, b, c, d))
forall (m :: * -> *) (z :: * -> *) a b c d r.
ZipM m z =>
(a -> b -> c -> d -> r) -> z a -> z b -> z c -> z d -> m (z r)
mzipWith4 (,,,)
    
    -- | Monadic 'zip5'.
    zipM5 :: z a -> z b -> z c -> z d -> z e -> m (z (a, b, c, d, e))
    zipM5 =  (a -> b -> c -> d -> e -> (a, b, c, d, e))
-> z a -> z b -> z c -> z d -> z e -> m (z (a, b, c, d, e))
forall (m :: * -> *) (z :: * -> *) a b c d e r.
ZipM m z =>
(a -> b -> c -> d -> e -> r)
-> z a -> z b -> z c -> z d -> z e -> m (z r)
mzipWith5 (,,,,)
    
    -- | Monadic 'zip6'.
    zipM6 :: z a -> z b -> z c -> z d -> z e -> z f -> m (z (a, b, c, d, e, f))
    zipM6 =  (a -> b -> c -> d -> e -> f -> (a, b, c, d, e, f))
-> z a
-> z b
-> z c
-> z d
-> z e
-> z f
-> m (z (a, b, c, d, e, f))
forall (m :: * -> *) (z :: * -> *) a b c d e f r.
ZipM m z =>
(a -> b -> c -> d -> e -> f -> r)
-> z a -> z b -> z c -> z d -> z e -> z f -> m (z r)
mzipWith6 (,,,,,)
    
    -- | Pure to monadic lifted 'zipWith'.
    mzipWith  :: (a -> b -> r) -> z a -> z b -> m (z r)
    mzipWith  a -> b -> r
g = (a -> b -> m r) -> z a -> z b -> m (z r)
forall (m :: * -> *) (z :: * -> *) a b r.
ZipM m z =>
(a -> b -> m r) -> z a -> z b -> m (z r)
zipWithM (\ a
a b
b -> r -> m r
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> b -> r
g a
a b
b))
    
    -- | Pure to monadic lifted 'zipWith3'.
    mzipWith3 :: (a -> b -> c -> r) -> z a -> z b -> z c -> m (z r)
    mzipWith3 a -> b -> c -> r
g = (a -> b -> c -> m r) -> z a -> z b -> z c -> m (z r)
forall (m :: * -> *) (z :: * -> *) a b c r.
ZipM m z =>
(a -> b -> c -> m r) -> z a -> z b -> z c -> m (z r)
zipWithM3 (\ a
a b
b c
c -> r -> m r
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> b -> c -> r
g a
a b
b c
c))
    
    -- | Pure to monadic lifted 'zipWith4'.
    mzipWith4 :: (a -> b -> c -> d -> r) -> z a -> z b -> z c -> z d -> m (z r)
    mzipWith4 a -> b -> c -> d -> r
g = (a -> b -> c -> d -> m r) -> z a -> z b -> z c -> z d -> m (z r)
forall (m :: * -> *) (z :: * -> *) a b c d r.
ZipM m z =>
(a -> b -> c -> d -> m r) -> z a -> z b -> z c -> z d -> m (z r)
zipWithM4 (\ a
a b
b c
c d
d -> r -> m r
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> b -> c -> d -> r
g a
a b
b c
c d
d))
    
    -- | Pure to monadic lifted 'zipWith5'.
    mzipWith5 :: (a -> b -> c -> d -> e -> r) -> z a -> z b -> z c -> z d -> z e -> m (z r)
    mzipWith5 a -> b -> c -> d -> e -> r
g = (a -> b -> c -> d -> e -> m r)
-> z a -> z b -> z c -> z d -> z e -> m (z r)
forall (m :: * -> *) (z :: * -> *) a b c d e r.
ZipM m z =>
(a -> b -> c -> d -> e -> m r)
-> z a -> z b -> z c -> z d -> z e -> m (z r)
zipWithM5 (\ a
a b
b c
c d
d e
e -> r -> m r
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> b -> c -> d -> e -> r
g a
a b
b c
c d
d e
e))
    
    -- | Pure to monadic lifted 'zipWith6'.
    mzipWith6 :: (a -> b -> c -> d -> e -> f -> r) -> z a -> z b -> z c -> z d -> z e -> z f -> m (z r)
    mzipWith6 a -> b -> c -> d -> e -> f -> r
g = (a -> b -> c -> d -> e -> f -> m r)
-> z a -> z b -> z c -> z d -> z e -> z f -> m (z r)
forall (m :: * -> *) (z :: * -> *) a b c d e f r.
ZipM m z =>
(a -> b -> c -> d -> e -> f -> m r)
-> z a -> z b -> z c -> z d -> z e -> z f -> m (z r)
zipWithM6 (\ a
a b
b c
c d
d e
e f
f -> r -> m r
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> b -> c -> d -> e -> f -> r
g a
a b
b c
c d
d e
e f
f))
    
    -- | Monadic 'zipWith'.
    zipWithM :: (a -> b -> m r) -> z a -> z b -> m (z r)
    
    -- | Monadic 'zipWith3'.
    zipWithM3 :: (a -> b -> c -> m r) -> z a -> z b -> z c -> m (z r)
    zipWithM3 a -> b -> c -> m r
f z a
za z b
zb z c
zc = ((c -> m r) -> c -> m r) -> z (c -> m r) -> z c -> m (z r)
forall (m :: * -> *) (z :: * -> *) a b r.
ZipM m z =>
(a -> b -> m r) -> z a -> z b -> m (z r)
zipWithM (c -> m r) -> c -> m r
forall a b. (a -> b) -> a -> b
($) (z (c -> m r) -> z c -> m (z r)) -> z c -> z (c -> m r) -> m (z r)
forall a b c. (a -> b -> c) -> b -> a -> c
`flip` z c
zc (z (c -> m r) -> m (z r)) -> m (z (c -> m r)) -> m (z r)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (a -> b -> c -> m r) -> z a -> z b -> m (z (c -> m r))
forall (m :: * -> *) (z :: * -> *) a b r.
ZipM m z =>
(a -> b -> r) -> z a -> z b -> m (z r)
mzipWith a -> b -> c -> m r
f z a
za z b
zb
    
    -- | Monadic 'zipWith4'.
    zipWithM4 :: (a -> b -> c -> d -> m r) -> z a -> z b -> z c -> z d -> m (z r)
    zipWithM4 a -> b -> c -> d -> m r
f z a
za z b
zb z c
zc z d
zd = ((d -> m r) -> d -> m r) -> z (d -> m r) -> z d -> m (z r)
forall (m :: * -> *) (z :: * -> *) a b r.
ZipM m z =>
(a -> b -> m r) -> z a -> z b -> m (z r)
zipWithM (d -> m r) -> d -> m r
forall a b. (a -> b) -> a -> b
($) (z (d -> m r) -> z d -> m (z r)) -> z d -> z (d -> m r) -> m (z r)
forall a b c. (a -> b -> c) -> b -> a -> c
`flip` z d
zd (z (d -> m r) -> m (z r)) -> m (z (d -> m r)) -> m (z r)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (a -> b -> c -> d -> m r) -> z a -> z b -> z c -> m (z (d -> m r))
forall (m :: * -> *) (z :: * -> *) a b c r.
ZipM m z =>
(a -> b -> c -> r) -> z a -> z b -> z c -> m (z r)
mzipWith3 a -> b -> c -> d -> m r
f z a
za z b
zb z c
zc
    
    -- | Monadic 'zipWith5'.
    zipWithM5 :: (a -> b -> c -> d -> e -> m r) -> z a -> z b -> z c -> z d -> z e -> m (z r)
    zipWithM5 a -> b -> c -> d -> e -> m r
f z a
za z b
zb z c
zc z d
zd z e
ze = ((e -> m r) -> e -> m r) -> z (e -> m r) -> z e -> m (z r)
forall (m :: * -> *) (z :: * -> *) a b r.
ZipM m z =>
(a -> b -> m r) -> z a -> z b -> m (z r)
zipWithM (e -> m r) -> e -> m r
forall a b. (a -> b) -> a -> b
($) (z (e -> m r) -> z e -> m (z r)) -> z e -> z (e -> m r) -> m (z r)
forall a b c. (a -> b -> c) -> b -> a -> c
`flip` z e
ze (z (e -> m r) -> m (z r)) -> m (z (e -> m r)) -> m (z r)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (a -> b -> c -> d -> e -> m r)
-> z a -> z b -> z c -> z d -> m (z (e -> m r))
forall (m :: * -> *) (z :: * -> *) a b c d r.
ZipM m z =>
(a -> b -> c -> d -> r) -> z a -> z b -> z c -> z d -> m (z r)
mzipWith4 a -> b -> c -> d -> e -> m r
f z a
za z b
zb z c
zc z d
zd
    
    -- | Monadic 'zipWith6'.
    zipWithM6 :: (a -> b -> c -> d -> e -> f -> m r) -> z a -> z b -> z c -> z d -> z e -> z f -> m (z r)
    zipWithM6 a -> b -> c -> d -> e -> f -> m r
f z a
za z b
zb z c
zc z d
zd z e
ze z f
zf = ((f -> m r) -> f -> m r) -> z (f -> m r) -> z f -> m (z r)
forall (m :: * -> *) (z :: * -> *) a b r.
ZipM m z =>
(a -> b -> m r) -> z a -> z b -> m (z r)
zipWithM (f -> m r) -> f -> m r
forall a b. (a -> b) -> a -> b
($) (z (f -> m r) -> z f -> m (z r)) -> z f -> z (f -> m r) -> m (z r)
forall a b c. (a -> b -> c) -> b -> a -> c
`flip` z f
zf (z (f -> m r) -> m (z r)) -> m (z (f -> m r)) -> m (z r)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (a -> b -> c -> d -> e -> f -> m r)
-> z a -> z b -> z c -> z d -> z e -> m (z (f -> m r))
forall (m :: * -> *) (z :: * -> *) a b c d e r.
ZipM m z =>
(a -> b -> c -> d -> e -> r)
-> z a -> z b -> z c -> z d -> z e -> m (z r)
mzipWith5 a -> b -> c -> d -> e -> f -> m r
f z a
za z b
zb z c
zc z d
zd z e
ze