{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Data.Singletons.Prelude.Monad.Zip (
PMonadZip(..), SMonadZip(..),
MzipSym0, MzipSym1, MzipSym2,
MzipWithSym0, MzipWithSym1, MzipWithSym2, MzipWithSym3,
MunzipSym0, MunzipSym1,
) where
import Control.Monad.Zip
import Data.Functor.Identity
import Data.Kind
import Data.Monoid
import Data.Singletons.Prelude.Identity
import Data.Singletons.Prelude.Instances
import Data.Singletons.Prelude.List
( ZipSym0, ZipWithSym0, UnzipSym0
, sZip, sZipWith, sUnzip )
import Data.Singletons.Prelude.Monad.Internal
import Data.Singletons.Prelude.Monoid ()
import Data.Singletons.Prelude.Tuple
import Data.Singletons.Single
$(singletonsOnly [d|
class Monad m => MonadZip (m :: Type -> Type) where
mzip :: m a -> m b -> m (a,b)
mzip = mzipWith (,)
mzipWith :: (a -> b -> c) -> m a -> m b -> m c
mzipWith f ma mb = liftM (uncurry f) (mzip ma mb)
munzip :: m (a,b) -> (m a, m b)
munzip mab = (liftM fst mab, liftM snd mab)
instance MonadZip [] where
mzip = zip
mzipWith = zipWith
munzip = unzip
instance MonadZip Identity where
mzipWith = liftM2
munzip (Identity (a, b)) = (Identity a, Identity b)
instance MonadZip Dual where
mzipWith = liftM2
instance MonadZip Sum where
mzipWith = liftM2
instance MonadZip Product where
mzipWith = liftM2
instance MonadZip Maybe where
mzipWith = liftM2
instance MonadZip First where
mzipWith = liftM2
instance MonadZip Last where
mzipWith = liftM2
|])