{-# LANGUAGE DeriveTraversable, StandaloneDeriving #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE PatternSynonyms #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  Data.Extensible.Wrapper
-- Copyright   :  (c) Fumiaki Kinoshita 2018
-- License     :  BSD3
--
-- Maintainer  :  Fumiaki Kinoshita <fumiexcel@gmail.com>
--
-----------------------------------------------------------------------------
module Data.Extensible.Wrapper (
  Wrapper(..)
  , _WrapperAs
  , type Comp
  , pattern Comp
  , getComp
  , comp
  , Prod(..)
  ) where

import Control.Applicative
import Control.DeepSeq
import Data.Typeable (Typeable)
import Data.Proxy (Proxy(..))
import Data.Profunctor.Unsafe (Profunctor(..))
import Data.Functor.Compose
import Data.Functor.Identity (Identity(..))
import Data.Extensible.Internal.Rig
import Data.Hashable
import Data.Kind (Type)
import GHC.Generics (Generic)
import Test.QuickCheck.Arbitrary


-- | The extensible data types should take @k -> Type@ as a parameter.
-- This class allows us to take a shortcut for direct representation.
class Wrapper (h :: k -> Type) where
  -- | @'Repr' h v@ is the user-facing representation of @h v@.
  type Repr h (v :: k) :: Type

  -- | This is an isomorphism between @h v@ and @'Repr' h v@.
  --
  -- @_Wrapper :: Iso' (h v) (Repr h v)@
  --
  _Wrapper :: (Functor f, Profunctor p) => Optic' p f (h v) (Repr h v)
  _Wrapper = (h v -> Repr h v)
-> (f (Repr h v) -> f (h v)) -> Optic' p f (h v) (Repr h v)
forall (p :: Type -> Type -> Type) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap h v -> Repr h v
forall k (h :: k -> Type) (v :: k). Wrapper h => h v -> Repr h v
unwrap ((Repr h v -> h v) -> f (Repr h v) -> f (h v)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap Repr h v -> h v
forall k (h :: k -> Type) (v :: k). Wrapper h => Repr h v -> h v
wrap)
  {-# INLINE _Wrapper #-}

  wrap :: Repr h v -> h v
  wrap = Optic' Tagged Identity (h v) (Repr h v) -> Repr h v -> h v
forall s a. Optic' Tagged Identity s a -> a -> s
review Optic' Tagged Identity (h v) (Repr h v)
forall k (h :: k -> Type) (f :: Type -> Type)
       (p :: Type -> Type -> Type) (v :: k).
(Wrapper h, Functor f, Profunctor p) =>
Optic' p f (h v) (Repr h v)
_Wrapper
  {-# INLINE wrap #-}

  unwrap :: h v -> Repr h v
  unwrap = Optic' (->) (Const (Repr h v)) (h v) (Repr h v) -> h v -> Repr h v
forall a s. Optic' (->) (Const a) s a -> s -> a
view Optic' (->) (Const (Repr h v)) (h v) (Repr h v)
forall k (h :: k -> Type) (f :: Type -> Type)
       (p :: Type -> Type -> Type) (v :: k).
(Wrapper h, Functor f, Profunctor p) =>
Optic' p f (h v) (Repr h v)
_Wrapper
  {-# INLINE unwrap #-}

  {-# MINIMAL wrap, unwrap | _Wrapper #-}

-- | Restricted version of '_Wrapper'.
-- It is useful for eliminating ambiguousness.
_WrapperAs :: (Functor f, Profunctor p, Wrapper h) => proxy v -> Optic' p f (h v) (Repr h v)
_WrapperAs :: proxy v -> Optic' p f (h v) (Repr h v)
_WrapperAs proxy v
_ = Optic' p f (h v) (Repr h v)
forall k (h :: k -> Type) (f :: Type -> Type)
       (p :: Type -> Type -> Type) (v :: k).
(Wrapper h, Functor f, Profunctor p) =>
Optic' p f (h v) (Repr h v)
_Wrapper
{-# INLINE _WrapperAs #-}

instance Wrapper Identity where
  type Repr Identity a = a
  unwrap :: Identity v -> Repr Identity v
unwrap = Identity v -> Repr Identity v
forall a. Identity a -> a
runIdentity
  {-# INLINE unwrap #-}
  wrap :: Repr Identity v -> Identity v
wrap = Repr Identity v -> Identity v
forall a. a -> Identity a
Identity
  {-# INLINE wrap #-}

instance Wrapper Maybe where
  type Repr Maybe a = Maybe a
  _Wrapper :: Optic' p f (Maybe v) (Repr Maybe v)
_Wrapper = Optic' p f (Maybe v) (Repr Maybe v)
forall a. a -> a
id

instance Wrapper (Either e) where
  type Repr (Either e) a = Either e a
  _Wrapper :: Optic' p f (Either e v) (Repr (Either e) v)
_Wrapper = Optic' p f (Either e v) (Repr (Either e) v)
forall a. a -> a
id

instance Wrapper [] where
  type Repr [] a = [a]
  _Wrapper :: Optic' p f [v] (Repr [] v)
_Wrapper = Optic' p f [v] (Repr [] v)
forall a. a -> a
id

type Comp = Compose

pattern Comp :: f (g a) -> Compose f g a
pattern $bComp :: f (g a) -> Compose f g a
$mComp :: forall r k k1 (f :: k -> Type) (g :: k1 -> k) (a :: k1).
Compose f g a -> (f (g a) -> r) -> (Void# -> r) -> r
Comp a = Compose a
{-# DEPRECATED Comp "Use Compose instead" #-}


getComp :: Compose f g a -> f (g a)
getComp :: Compose f g a -> f (g a)
getComp = Compose f g a -> f (g a)
forall k1 (f :: k1 -> Type) k2 (g :: k2 -> k1) (a :: k2).
Compose f g a -> f (g a)
getCompose
{-# DEPRECATED getComp "Use getCompose instead" #-}

-- | Wrap a result of 'fmap'
comp :: Functor f => (a -> g b) -> f a -> Compose f g b
comp :: (a -> g b) -> f a -> Compose f g b
comp a -> g b
f = f (g b) -> Compose f g b
forall k k1 (f :: k -> Type) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose (f (g b) -> Compose f g b)
-> (f a -> f (g b)) -> f a -> Compose f g b
forall (p :: Type -> Type -> Type) a b c
       (q :: Type -> Type -> Type).
(Profunctor p, Coercible c b) =>
q b c -> p a b -> p a c
#. (a -> g b) -> f a -> f (g b)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> g b
f
{-# INLINE comp #-}

instance (Functor f, Wrapper g) => Wrapper (Compose f g) where
  type Repr (Compose f g) x = f (Repr g x)
  _Wrapper :: Optic' p f (Compose f g v) (Repr (Compose f g) v)
_Wrapper = Optic
  (Exchange (Repr g v) (Repr g v))
  Identity
  (g v)
  (g v)
  (Repr g v)
  (Repr g v)
-> ((g v -> Repr g v)
    -> (Repr g v -> g v)
    -> p (f (Repr g v)) (f (f (Repr g v)))
    -> p (Compose f g v) (f (Compose f g v)))
-> p (f (Repr g v)) (f (f (Repr g v)))
-> p (Compose f g v) (f (Compose f g v))
forall a b s t r.
Optic (Exchange a b) Identity s t a b
-> ((s -> a) -> (b -> t) -> r) -> r
withIso Optic
  (Exchange (Repr g v) (Repr g v))
  Identity
  (g v)
  (g v)
  (Repr g v)
  (Repr g v)
forall k (h :: k -> Type) (f :: Type -> Type)
       (p :: Type -> Type -> Type) (v :: k).
(Wrapper h, Functor f, Profunctor p) =>
Optic' p f (h v) (Repr h v)
_Wrapper (((g v -> Repr g v)
  -> (Repr g v -> g v)
  -> p (f (Repr g v)) (f (f (Repr g v)))
  -> p (Compose f g v) (f (Compose f g v)))
 -> p (f (Repr g v)) (f (f (Repr g v)))
 -> p (Compose f g v) (f (Compose f g v)))
-> ((g v -> Repr g v)
    -> (Repr g v -> g v)
    -> p (f (Repr g v)) (f (f (Repr g v)))
    -> p (Compose f g v) (f (Compose f g v)))
-> p (f (Repr g v)) (f (f (Repr g v)))
-> p (Compose f g v) (f (Compose f g v))
forall a b. (a -> b) -> a -> b
$ \g v -> Repr g v
f Repr g v -> g v
g -> (Compose f g v -> f (Repr g v))
-> (f (f (Repr g v)) -> f (Compose f g v))
-> p (f (Repr g v)) (f (f (Repr g v)))
-> p (Compose f g v) (f (Compose f g v))
forall (p :: Type -> Type -> Type) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap ((g v -> Repr g v) -> f (g v) -> f (Repr g v)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap g v -> Repr g v
f (f (g v) -> f (Repr g v))
-> (Compose f g v -> f (g v)) -> Compose f g v -> f (Repr g v)
forall (p :: Type -> Type -> Type) a b c
       (q :: Type -> Type -> Type).
(Profunctor p, Coercible b a) =>
p b c -> q a b -> p a c
.# Compose f g v -> f (g v)
forall k1 (f :: k1 -> Type) k2 (g :: k2 -> k1) (a :: k2).
Compose f g a -> f (g a)
getCompose) ((f (Repr g v) -> Compose f g v)
-> f (f (Repr g v)) -> f (Compose f g v)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Repr g v -> g v) -> f (Repr g v) -> Compose f g v
forall k1 (f :: Type -> Type) a (g :: k1 -> Type) (b :: k1).
Functor f =>
(a -> g b) -> f a -> Compose f g b
comp Repr g v -> g v
g))
  {-# INLINE _Wrapper #-}

instance Wrapper (Const a) where
  type Repr (Const a) b = a
  wrap :: Repr (Const a) v -> Const a v
wrap = Repr (Const a) v -> Const a v
forall k a (b :: k). a -> Const a b
Const
  {-# INLINE wrap #-}
  unwrap :: Const a v -> Repr (Const a) v
unwrap = Const a v -> Repr (Const a) v
forall a k (b :: k). Const a b -> a
getConst
  {-# INLINE unwrap #-}

instance Wrapper Proxy where
  type Repr Proxy x = ()
  wrap :: Repr Proxy v -> Proxy v
wrap Repr Proxy v
_ = Proxy v
forall k (t :: k). Proxy t
Proxy
  {-# INLINE wrap #-}
  unwrap :: Proxy v -> Repr Proxy v
unwrap Proxy v
_ = ()
  {-# INLINE unwrap #-}

-- | Poly-kinded product
data Prod f g a = Prod (f a) (g a)
  deriving (Int -> Prod f g a -> ShowS
[Prod f g a] -> ShowS
Prod f g a -> String
(Int -> Prod f g a -> ShowS)
-> (Prod f g a -> String)
-> ([Prod f g a] -> ShowS)
-> Show (Prod f g a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
(Show (f a), Show (g a)) =>
Int -> Prod f g a -> ShowS
forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
(Show (f a), Show (g a)) =>
[Prod f g a] -> ShowS
forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
(Show (f a), Show (g a)) =>
Prod f g a -> String
showList :: [Prod f g a] -> ShowS
$cshowList :: forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
(Show (f a), Show (g a)) =>
[Prod f g a] -> ShowS
show :: Prod f g a -> String
$cshow :: forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
(Show (f a), Show (g a)) =>
Prod f g a -> String
showsPrec :: Int -> Prod f g a -> ShowS
$cshowsPrec :: forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
(Show (f a), Show (g a)) =>
Int -> Prod f g a -> ShowS
Show, Prod f g a -> Prod f g a -> Bool
(Prod f g a -> Prod f g a -> Bool)
-> (Prod f g a -> Prod f g a -> Bool) -> Eq (Prod f g a)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
(Eq (f a), Eq (g a)) =>
Prod f g a -> Prod f g a -> Bool
/= :: Prod f g a -> Prod f g a -> Bool
$c/= :: forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
(Eq (f a), Eq (g a)) =>
Prod f g a -> Prod f g a -> Bool
== :: Prod f g a -> Prod f g a -> Bool
$c== :: forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
(Eq (f a), Eq (g a)) =>
Prod f g a -> Prod f g a -> Bool
Eq, Eq (Prod f g a)
Eq (Prod f g a)
-> (Prod f g a -> Prod f g a -> Ordering)
-> (Prod f g a -> Prod f g a -> Bool)
-> (Prod f g a -> Prod f g a -> Bool)
-> (Prod f g a -> Prod f g a -> Bool)
-> (Prod f g a -> Prod f g a -> Bool)
-> (Prod f g a -> Prod f g a -> Prod f g a)
-> (Prod f g a -> Prod f g a -> Prod f g a)
-> Ord (Prod f g a)
Prod f g a -> Prod f g a -> Bool
Prod f g a -> Prod f g a -> Ordering
Prod f g a -> Prod f g a -> Prod f g a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
(Ord (f a), Ord (g a)) =>
Eq (Prod f g a)
forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
(Ord (f a), Ord (g a)) =>
Prod f g a -> Prod f g a -> Bool
forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
(Ord (f a), Ord (g a)) =>
Prod f g a -> Prod f g a -> Ordering
forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
(Ord (f a), Ord (g a)) =>
Prod f g a -> Prod f g a -> Prod f g a
min :: Prod f g a -> Prod f g a -> Prod f g a
$cmin :: forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
(Ord (f a), Ord (g a)) =>
Prod f g a -> Prod f g a -> Prod f g a
max :: Prod f g a -> Prod f g a -> Prod f g a
$cmax :: forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
(Ord (f a), Ord (g a)) =>
Prod f g a -> Prod f g a -> Prod f g a
>= :: Prod f g a -> Prod f g a -> Bool
$c>= :: forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
(Ord (f a), Ord (g a)) =>
Prod f g a -> Prod f g a -> Bool
> :: Prod f g a -> Prod f g a -> Bool
$c> :: forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
(Ord (f a), Ord (g a)) =>
Prod f g a -> Prod f g a -> Bool
<= :: Prod f g a -> Prod f g a -> Bool
$c<= :: forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
(Ord (f a), Ord (g a)) =>
Prod f g a -> Prod f g a -> Bool
< :: Prod f g a -> Prod f g a -> Bool
$c< :: forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
(Ord (f a), Ord (g a)) =>
Prod f g a -> Prod f g a -> Bool
compare :: Prod f g a -> Prod f g a -> Ordering
$ccompare :: forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
(Ord (f a), Ord (g a)) =>
Prod f g a -> Prod f g a -> Ordering
$cp1Ord :: forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
(Ord (f a), Ord (g a)) =>
Eq (Prod f g a)
Ord, Typeable, (forall x. Prod f g a -> Rep (Prod f g a) x)
-> (forall x. Rep (Prod f g a) x -> Prod f g a)
-> Generic (Prod f g a)
forall x. Rep (Prod f g a) x -> Prod f g a
forall x. Prod f g a -> Rep (Prod f g a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall k (f :: k -> Type) (g :: k -> Type) (a :: k) x.
Rep (Prod f g a) x -> Prod f g a
forall k (f :: k -> Type) (g :: k -> Type) (a :: k) x.
Prod f g a -> Rep (Prod f g a) x
$cto :: forall k (f :: k -> Type) (g :: k -> Type) (a :: k) x.
Rep (Prod f g a) x -> Prod f g a
$cfrom :: forall k (f :: k -> Type) (g :: k -> Type) (a :: k) x.
Prod f g a -> Rep (Prod f g a) x
Generic, a -> Prod f g b -> Prod f g a
(a -> b) -> Prod f g a -> Prod f g b
(forall a b. (a -> b) -> Prod f g a -> Prod f g b)
-> (forall a b. a -> Prod f g b -> Prod f g a)
-> Functor (Prod f g)
forall a b. a -> Prod f g b -> Prod f g a
forall a b. (a -> b) -> Prod f g a -> Prod f g b
forall (f :: Type -> Type).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
forall (f :: Type -> Type) (g :: Type -> Type) a b.
(Functor f, Functor g) =>
a -> Prod f g b -> Prod f g a
forall (f :: Type -> Type) (g :: Type -> Type) a b.
(Functor f, Functor g) =>
(a -> b) -> Prod f g a -> Prod f g b
<$ :: a -> Prod f g b -> Prod f g a
$c<$ :: forall (f :: Type -> Type) (g :: Type -> Type) a b.
(Functor f, Functor g) =>
a -> Prod f g b -> Prod f g a
fmap :: (a -> b) -> Prod f g a -> Prod f g b
$cfmap :: forall (f :: Type -> Type) (g :: Type -> Type) a b.
(Functor f, Functor g) =>
(a -> b) -> Prod f g a -> Prod f g b
Functor, Prod f g a -> Bool
(a -> m) -> Prod f g a -> m
(a -> b -> b) -> b -> Prod f g a -> b
(forall m. Monoid m => Prod f g m -> m)
-> (forall m a. Monoid m => (a -> m) -> Prod f g a -> m)
-> (forall m a. Monoid m => (a -> m) -> Prod f g a -> m)
-> (forall a b. (a -> b -> b) -> b -> Prod f g a -> b)
-> (forall a b. (a -> b -> b) -> b -> Prod f g a -> b)
-> (forall b a. (b -> a -> b) -> b -> Prod f g a -> b)
-> (forall b a. (b -> a -> b) -> b -> Prod f g a -> b)
-> (forall a. (a -> a -> a) -> Prod f g a -> a)
-> (forall a. (a -> a -> a) -> Prod f g a -> a)
-> (forall a. Prod f g a -> [a])
-> (forall a. Prod f g a -> Bool)
-> (forall a. Prod f g a -> Int)
-> (forall a. Eq a => a -> Prod f g a -> Bool)
-> (forall a. Ord a => Prod f g a -> a)
-> (forall a. Ord a => Prod f g a -> a)
-> (forall a. Num a => Prod f g a -> a)
-> (forall a. Num a => Prod f g a -> a)
-> Foldable (Prod f g)
forall a. Eq a => a -> Prod f g a -> Bool
forall a. Num a => Prod f g a -> a
forall a. Ord a => Prod f g a -> a
forall m. Monoid m => Prod f g m -> m
forall a. Prod f g a -> Bool
forall a. Prod f g a -> Int
forall a. Prod f g a -> [a]
forall a. (a -> a -> a) -> Prod f g a -> a
forall m a. Monoid m => (a -> m) -> Prod f g a -> m
forall b a. (b -> a -> b) -> b -> Prod f g a -> b
forall a b. (a -> b -> b) -> b -> Prod f g a -> b
forall (t :: Type -> Type).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
forall (f :: Type -> Type) (g :: Type -> Type) a.
(Foldable f, Foldable g, Eq a) =>
a -> Prod f g a -> Bool
forall (f :: Type -> Type) (g :: Type -> Type) a.
(Foldable f, Foldable g, Num a) =>
Prod f g a -> a
forall (f :: Type -> Type) (g :: Type -> Type) a.
(Foldable f, Foldable g, Ord a) =>
Prod f g a -> a
forall (f :: Type -> Type) (g :: Type -> Type) m.
(Foldable f, Foldable g, Monoid m) =>
Prod f g m -> m
forall (f :: Type -> Type) (g :: Type -> Type) a.
(Foldable f, Foldable g) =>
Prod f g a -> Bool
forall (f :: Type -> Type) (g :: Type -> Type) a.
(Foldable f, Foldable g) =>
Prod f g a -> Int
forall (f :: Type -> Type) (g :: Type -> Type) a.
(Foldable f, Foldable g) =>
Prod f g a -> [a]
forall (f :: Type -> Type) (g :: Type -> Type) a.
(Foldable f, Foldable g) =>
(a -> a -> a) -> Prod f g a -> a
forall (f :: Type -> Type) (g :: Type -> Type) m a.
(Foldable f, Foldable g, Monoid m) =>
(a -> m) -> Prod f g a -> m
forall (f :: Type -> Type) (g :: Type -> Type) b a.
(Foldable f, Foldable g) =>
(b -> a -> b) -> b -> Prod f g a -> b
forall (f :: Type -> Type) (g :: Type -> Type) a b.
(Foldable f, Foldable g) =>
(a -> b -> b) -> b -> Prod f g a -> b
product :: Prod f g a -> a
$cproduct :: forall (f :: Type -> Type) (g :: Type -> Type) a.
(Foldable f, Foldable g, Num a) =>
Prod f g a -> a
sum :: Prod f g a -> a
$csum :: forall (f :: Type -> Type) (g :: Type -> Type) a.
(Foldable f, Foldable g, Num a) =>
Prod f g a -> a
minimum :: Prod f g a -> a
$cminimum :: forall (f :: Type -> Type) (g :: Type -> Type) a.
(Foldable f, Foldable g, Ord a) =>
Prod f g a -> a
maximum :: Prod f g a -> a
$cmaximum :: forall (f :: Type -> Type) (g :: Type -> Type) a.
(Foldable f, Foldable g, Ord a) =>
Prod f g a -> a
elem :: a -> Prod f g a -> Bool
$celem :: forall (f :: Type -> Type) (g :: Type -> Type) a.
(Foldable f, Foldable g, Eq a) =>
a -> Prod f g a -> Bool
length :: Prod f g a -> Int
$clength :: forall (f :: Type -> Type) (g :: Type -> Type) a.
(Foldable f, Foldable g) =>
Prod f g a -> Int
null :: Prod f g a -> Bool
$cnull :: forall (f :: Type -> Type) (g :: Type -> Type) a.
(Foldable f, Foldable g) =>
Prod f g a -> Bool
toList :: Prod f g a -> [a]
$ctoList :: forall (f :: Type -> Type) (g :: Type -> Type) a.
(Foldable f, Foldable g) =>
Prod f g a -> [a]
foldl1 :: (a -> a -> a) -> Prod f g a -> a
$cfoldl1 :: forall (f :: Type -> Type) (g :: Type -> Type) a.
(Foldable f, Foldable g) =>
(a -> a -> a) -> Prod f g a -> a
foldr1 :: (a -> a -> a) -> Prod f g a -> a
$cfoldr1 :: forall (f :: Type -> Type) (g :: Type -> Type) a.
(Foldable f, Foldable g) =>
(a -> a -> a) -> Prod f g a -> a
foldl' :: (b -> a -> b) -> b -> Prod f g a -> b
$cfoldl' :: forall (f :: Type -> Type) (g :: Type -> Type) b a.
(Foldable f, Foldable g) =>
(b -> a -> b) -> b -> Prod f g a -> b
foldl :: (b -> a -> b) -> b -> Prod f g a -> b
$cfoldl :: forall (f :: Type -> Type) (g :: Type -> Type) b a.
(Foldable f, Foldable g) =>
(b -> a -> b) -> b -> Prod f g a -> b
foldr' :: (a -> b -> b) -> b -> Prod f g a -> b
$cfoldr' :: forall (f :: Type -> Type) (g :: Type -> Type) a b.
(Foldable f, Foldable g) =>
(a -> b -> b) -> b -> Prod f g a -> b
foldr :: (a -> b -> b) -> b -> Prod f g a -> b
$cfoldr :: forall (f :: Type -> Type) (g :: Type -> Type) a b.
(Foldable f, Foldable g) =>
(a -> b -> b) -> b -> Prod f g a -> b
foldMap' :: (a -> m) -> Prod f g a -> m
$cfoldMap' :: forall (f :: Type -> Type) (g :: Type -> Type) m a.
(Foldable f, Foldable g, Monoid m) =>
(a -> m) -> Prod f g a -> m
foldMap :: (a -> m) -> Prod f g a -> m
$cfoldMap :: forall (f :: Type -> Type) (g :: Type -> Type) m a.
(Foldable f, Foldable g, Monoid m) =>
(a -> m) -> Prod f g a -> m
fold :: Prod f g m -> m
$cfold :: forall (f :: Type -> Type) (g :: Type -> Type) m.
(Foldable f, Foldable g, Monoid m) =>
Prod f g m -> m
Foldable, Functor (Prod f g)
Foldable (Prod f g)
Functor (Prod f g)
-> Foldable (Prod f g)
-> (forall (f :: Type -> Type) a b.
    Applicative f =>
    (a -> f b) -> Prod f g a -> f (Prod f g b))
-> (forall (f :: Type -> Type) a.
    Applicative f =>
    Prod f g (f a) -> f (Prod f g a))
-> (forall (m :: Type -> Type) a b.
    Monad m =>
    (a -> m b) -> Prod f g a -> m (Prod f g b))
-> (forall (m :: Type -> Type) a.
    Monad m =>
    Prod f g (m a) -> m (Prod f g a))
-> Traversable (Prod f g)
(a -> f b) -> Prod f g a -> f (Prod f g b)
forall (t :: Type -> Type).
Functor t
-> Foldable t
-> (forall (f :: Type -> Type) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: Type -> Type) a.
    Applicative f =>
    t (f a) -> f (t a))
-> (forall (m :: Type -> Type) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: Type -> Type) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: Type -> Type) a.
Monad m =>
Prod f g (m a) -> m (Prod f g a)
forall (f :: Type -> Type) a.
Applicative f =>
Prod f g (f a) -> f (Prod f g a)
forall (m :: Type -> Type) a b.
Monad m =>
(a -> m b) -> Prod f g a -> m (Prod f g b)
forall (f :: Type -> Type) a b.
Applicative f =>
(a -> f b) -> Prod f g a -> f (Prod f g b)
forall (f :: Type -> Type) (g :: Type -> Type).
(Traversable f, Traversable g) =>
Functor (Prod f g)
forall (f :: Type -> Type) (g :: Type -> Type).
(Traversable f, Traversable g) =>
Foldable (Prod f g)
forall (f :: Type -> Type) (g :: Type -> Type) (m :: Type -> Type)
       a.
(Traversable f, Traversable g, Monad m) =>
Prod f g (m a) -> m (Prod f g a)
forall (f :: Type -> Type) (g :: Type -> Type) (f :: Type -> Type)
       a.
(Traversable f, Traversable g, Applicative f) =>
Prod f g (f a) -> f (Prod f g a)
forall (f :: Type -> Type) (g :: Type -> Type) (m :: Type -> Type)
       a b.
(Traversable f, Traversable g, Monad m) =>
(a -> m b) -> Prod f g a -> m (Prod f g b)
forall (f :: Type -> Type) (g :: Type -> Type) (f :: Type -> Type)
       a b.
(Traversable f, Traversable g, Applicative f) =>
(a -> f b) -> Prod f g a -> f (Prod f g b)
sequence :: Prod f g (m a) -> m (Prod f g a)
$csequence :: forall (f :: Type -> Type) (g :: Type -> Type) (m :: Type -> Type)
       a.
(Traversable f, Traversable g, Monad m) =>
Prod f g (m a) -> m (Prod f g a)
mapM :: (a -> m b) -> Prod f g a -> m (Prod f g b)
$cmapM :: forall (f :: Type -> Type) (g :: Type -> Type) (m :: Type -> Type)
       a b.
(Traversable f, Traversable g, Monad m) =>
(a -> m b) -> Prod f g a -> m (Prod f g b)
sequenceA :: Prod f g (f a) -> f (Prod f g a)
$csequenceA :: forall (f :: Type -> Type) (g :: Type -> Type) (f :: Type -> Type)
       a.
(Traversable f, Traversable g, Applicative f) =>
Prod f g (f a) -> f (Prod f g a)
traverse :: (a -> f b) -> Prod f g a -> f (Prod f g b)
$ctraverse :: forall (f :: Type -> Type) (g :: Type -> Type) (f :: Type -> Type)
       a b.
(Traversable f, Traversable g, Applicative f) =>
(a -> f b) -> Prod f g a -> f (Prod f g b)
$cp2Traversable :: forall (f :: Type -> Type) (g :: Type -> Type).
(Traversable f, Traversable g) =>
Foldable (Prod f g)
$cp1Traversable :: forall (f :: Type -> Type) (g :: Type -> Type).
(Traversable f, Traversable g) =>
Functor (Prod f g)
Traversable)

instance (NFData (f a), NFData (g a)) => NFData (Prod f g a)
instance (Hashable (f a), Hashable (g a)) => Hashable (Prod f g a)

instance (Wrapper f, Wrapper g) => Wrapper (Prod f g) where
  type Repr (Prod f g) a = (Repr f a, Repr g a)
  unwrap :: Prod f g v -> Repr (Prod f g) v
unwrap (Prod f v
f g v
g) = (f v -> Repr f v
forall k (h :: k -> Type) (v :: k). Wrapper h => h v -> Repr h v
unwrap f v
f, g v -> Repr g v
forall k (h :: k -> Type) (v :: k). Wrapper h => h v -> Repr h v
unwrap g v
g)
  {-# INLINE unwrap #-}
  wrap :: Repr (Prod f g) v -> Prod f g v
wrap (f, g) = Repr f v -> f v
forall k (h :: k -> Type) (v :: k). Wrapper h => Repr h v -> h v
wrap Repr f v
f f v -> g v -> Prod f g v
forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
f a -> g a -> Prod f g a
`Prod` Repr g v -> g v
forall k (h :: k -> Type) (v :: k). Wrapper h => Repr h v -> h v
wrap Repr g v
g
  {-# INLINE wrap #-}

instance (Semigroup (f a), Semigroup (g a)) => Semigroup (Prod f g a) where
  Prod f a
a g a
b <> :: Prod f g a -> Prod f g a -> Prod f g a
<> Prod f a
c g a
d = f a -> g a -> Prod f g a
forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
f a -> g a -> Prod f g a
Prod (f a
a f a -> f a -> f a
forall a. Semigroup a => a -> a -> a
<> f a
c) (g a
b g a -> g a -> g a
forall a. Semigroup a => a -> a -> a
<> g a
d)

instance (Monoid (f a), Monoid (g a)) => Monoid (Prod f g a) where
  mempty :: Prod f g a
mempty = f a -> g a -> Prod f g a
forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
f a -> g a -> Prod f g a
Prod f a
forall a. Monoid a => a
mempty g a
forall a. Monoid a => a
mempty
  mappend :: Prod f g a -> Prod f g a -> Prod f g a
mappend = Prod f g a -> Prod f g a -> Prod f g a
forall a. Semigroup a => a -> a -> a
(<>)

instance (Arbitrary (f a), Arbitrary (g a)) => Arbitrary (Prod f g a) where
  arbitrary :: Gen (Prod f g a)
arbitrary = f a -> g a -> Prod f g a
forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
f a -> g a -> Prod f g a
Prod (f a -> g a -> Prod f g a) -> Gen (f a) -> Gen (g a -> Prod f g a)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (f a)
forall a. Arbitrary a => Gen a
arbitrary Gen (g a -> Prod f g a) -> Gen (g a) -> Gen (Prod f g a)
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Gen (g a)
forall a. Arbitrary a => Gen a
arbitrary
  shrink :: Prod f g a -> [Prod f g a]
shrink (Prod f a
a g a
b) = f a -> g a -> Prod f g a
forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
f a -> g a -> Prod f g a
Prod f a
a (g a -> Prod f g a) -> [g a] -> [Prod f g a]
forall a b. (a -> b) -> [a] -> [b]
`map` g a -> [g a]
forall a. Arbitrary a => a -> [a]
shrink g a
b [Prod f g a] -> [Prod f g a] -> [Prod f g a]
forall a. [a] -> [a] -> [a]
++ (f a -> g a -> Prod f g a) -> g a -> f a -> Prod f g a
forall a b c. (a -> b -> c) -> b -> a -> c
flip f a -> g a -> Prod f g a
forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
f a -> g a -> Prod f g a
Prod g a
b (f a -> Prod f g a) -> [f a] -> [Prod f g a]
forall a b. (a -> b) -> [a] -> [b]
`map` f a -> [f a]
forall a. Arbitrary a => a -> [a]
shrink f a
a