{-# LANGUAGE DeriveTraversable, StandaloneDeriving #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TemplateHaskell #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  Data.Extensible.Wrapper
-- Copyright   :  (c) Fumiaki Kinoshita 2018
-- License     :  BSD3
--
-- Maintainer  :  Fumiaki Kinoshita <fumiexcel@gmail.com>
--
-----------------------------------------------------------------------------
module Data.Extensible.Wrapper (
  Wrapper(..)
  , _WrapperAs
  , Comp(..)
  , 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.Identity (Identity(..))
import Data.Extensible.Internal.Rig
import Data.Hashable
import Data.Kind (Type)
import Data.Text.Prettyprint.Doc
import GHC.Generics (Generic)
import Language.Haskell.TH.Lift
import Language.Haskell.TH (conE, appE)
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

-- | Poly-kinded composition
newtype Comp (f :: j -> Type) (g :: i -> j) (a :: i) = Comp { Comp f g a -> f (g a)
getComp :: f (g a) }
  deriving (Int -> Comp f g a -> ShowS
[Comp f g a] -> ShowS
Comp f g a -> String
(Int -> Comp f g a -> ShowS)
-> (Comp f g a -> String)
-> ([Comp f g a] -> ShowS)
-> Show (Comp f g a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Show (f (g a)) =>
Int -> Comp f g a -> ShowS
forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Show (f (g a)) =>
[Comp f g a] -> ShowS
forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Show (f (g a)) =>
Comp f g a -> String
showList :: [Comp f g a] -> ShowS
$cshowList :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Show (f (g a)) =>
[Comp f g a] -> ShowS
show :: Comp f g a -> String
$cshow :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Show (f (g a)) =>
Comp f g a -> String
showsPrec :: Int -> Comp f g a -> ShowS
$cshowsPrec :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Show (f (g a)) =>
Int -> Comp f g a -> ShowS
Show, Comp f g a -> Comp f g a -> Bool
(Comp f g a -> Comp f g a -> Bool)
-> (Comp f g a -> Comp f g a -> Bool) -> Eq (Comp f g a)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Eq (f (g a)) =>
Comp f g a -> Comp f g a -> Bool
/= :: Comp f g a -> Comp f g a -> Bool
$c/= :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Eq (f (g a)) =>
Comp f g a -> Comp f g a -> Bool
== :: Comp f g a -> Comp f g a -> Bool
$c== :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Eq (f (g a)) =>
Comp f g a -> Comp f g a -> Bool
Eq, Eq (Comp f g a)
Eq (Comp f g a)
-> (Comp f g a -> Comp f g a -> Ordering)
-> (Comp f g a -> Comp f g a -> Bool)
-> (Comp f g a -> Comp f g a -> Bool)
-> (Comp f g a -> Comp f g a -> Bool)
-> (Comp f g a -> Comp f g a -> Bool)
-> (Comp f g a -> Comp f g a -> Comp f g a)
-> (Comp f g a -> Comp f g a -> Comp f g a)
-> Ord (Comp f g a)
Comp f g a -> Comp f g a -> Bool
Comp f g a -> Comp f g a -> Ordering
Comp f g a -> Comp f g a -> Comp 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 j (f :: j -> Type) i (g :: i -> j) (a :: i).
Ord (f (g a)) =>
Eq (Comp f g a)
forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Ord (f (g a)) =>
Comp f g a -> Comp f g a -> Bool
forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Ord (f (g a)) =>
Comp f g a -> Comp f g a -> Ordering
forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Ord (f (g a)) =>
Comp f g a -> Comp f g a -> Comp f g a
min :: Comp f g a -> Comp f g a -> Comp f g a
$cmin :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Ord (f (g a)) =>
Comp f g a -> Comp f g a -> Comp f g a
max :: Comp f g a -> Comp f g a -> Comp f g a
$cmax :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Ord (f (g a)) =>
Comp f g a -> Comp f g a -> Comp f g a
>= :: Comp f g a -> Comp f g a -> Bool
$c>= :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Ord (f (g a)) =>
Comp f g a -> Comp f g a -> Bool
> :: Comp f g a -> Comp f g a -> Bool
$c> :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Ord (f (g a)) =>
Comp f g a -> Comp f g a -> Bool
<= :: Comp f g a -> Comp f g a -> Bool
$c<= :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Ord (f (g a)) =>
Comp f g a -> Comp f g a -> Bool
< :: Comp f g a -> Comp f g a -> Bool
$c< :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Ord (f (g a)) =>
Comp f g a -> Comp f g a -> Bool
compare :: Comp f g a -> Comp f g a -> Ordering
$ccompare :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Ord (f (g a)) =>
Comp f g a -> Comp f g a -> Ordering
$cp1Ord :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Ord (f (g a)) =>
Eq (Comp f g a)
Ord, Typeable, Comp f g a -> ()
(Comp f g a -> ()) -> NFData (Comp f g a)
forall a. (a -> ()) -> NFData a
forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
NFData (f (g a)) =>
Comp f g a -> ()
rnf :: Comp f g a -> ()
$crnf :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
NFData (f (g a)) =>
Comp f g a -> ()
NFData, (forall x. Comp f g a -> Rep (Comp f g a) x)
-> (forall x. Rep (Comp f g a) x -> Comp f g a)
-> Generic (Comp f g a)
forall x. Rep (Comp f g a) x -> Comp f g a
forall x. Comp f g a -> Rep (Comp f g a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall j (f :: j -> Type) i (g :: i -> j) (a :: i) x.
Rep (Comp f g a) x -> Comp f g a
forall j (f :: j -> Type) i (g :: i -> j) (a :: i) x.
Comp f g a -> Rep (Comp f g a) x
$cto :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i) x.
Rep (Comp f g a) x -> Comp f g a
$cfrom :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i) x.
Comp f g a -> Rep (Comp f g a) x
Generic, b -> Comp f g a -> Comp f g a
NonEmpty (Comp f g a) -> Comp f g a
Comp f g a -> Comp f g a -> Comp f g a
(Comp f g a -> Comp f g a -> Comp f g a)
-> (NonEmpty (Comp f g a) -> Comp f g a)
-> (forall b. Integral b => b -> Comp f g a -> Comp f g a)
-> Semigroup (Comp f g a)
forall b. Integral b => b -> Comp f g a -> Comp f g a
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Semigroup (f (g a)) =>
NonEmpty (Comp f g a) -> Comp f g a
forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Semigroup (f (g a)) =>
Comp f g a -> Comp f g a -> Comp f g a
forall j (f :: j -> Type) i (g :: i -> j) (a :: i) b.
(Semigroup (f (g a)), Integral b) =>
b -> Comp f g a -> Comp f g a
stimes :: b -> Comp f g a -> Comp f g a
$cstimes :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i) b.
(Semigroup (f (g a)), Integral b) =>
b -> Comp f g a -> Comp f g a
sconcat :: NonEmpty (Comp f g a) -> Comp f g a
$csconcat :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Semigroup (f (g a)) =>
NonEmpty (Comp f g a) -> Comp f g a
<> :: Comp f g a -> Comp f g a -> Comp f g a
$c<> :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Semigroup (f (g a)) =>
Comp f g a -> Comp f g a -> Comp f g a
Semigroup, Semigroup (Comp f g a)
Comp f g a
Semigroup (Comp f g a)
-> Comp f g a
-> (Comp f g a -> Comp f g a -> Comp f g a)
-> ([Comp f g a] -> Comp f g a)
-> Monoid (Comp f g a)
[Comp f g a] -> Comp f g a
Comp f g a -> Comp f g a -> Comp f g a
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Monoid (f (g a)) =>
Semigroup (Comp f g a)
forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Monoid (f (g a)) =>
Comp f g a
forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Monoid (f (g a)) =>
[Comp f g a] -> Comp f g a
forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Monoid (f (g a)) =>
Comp f g a -> Comp f g a -> Comp f g a
mconcat :: [Comp f g a] -> Comp f g a
$cmconcat :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Monoid (f (g a)) =>
[Comp f g a] -> Comp f g a
mappend :: Comp f g a -> Comp f g a -> Comp f g a
$cmappend :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Monoid (f (g a)) =>
Comp f g a -> Comp f g a -> Comp f g a
mempty :: Comp f g a
$cmempty :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Monoid (f (g a)) =>
Comp f g a
$cp1Monoid :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Monoid (f (g a)) =>
Semigroup (Comp f g a)
Monoid, Gen (Comp f g a)
Gen (Comp f g a)
-> (Comp f g a -> [Comp f g a]) -> Arbitrary (Comp f g a)
Comp f g a -> [Comp f g a]
forall a. Gen a -> (a -> [a]) -> Arbitrary a
forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Arbitrary (f (g a)) =>
Gen (Comp f g a)
forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Arbitrary (f (g a)) =>
Comp f g a -> [Comp f g a]
shrink :: Comp f g a -> [Comp f g a]
$cshrink :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Arbitrary (f (g a)) =>
Comp f g a -> [Comp f g a]
arbitrary :: Gen (Comp f g a)
$carbitrary :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Arbitrary (f (g a)) =>
Gen (Comp f g a)
Arbitrary, Int -> Comp f g a -> Int
Comp f g a -> Int
(Int -> Comp f g a -> Int)
-> (Comp f g a -> Int) -> Hashable (Comp f g a)
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Hashable (f (g a)) =>
Int -> Comp f g a -> Int
forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Hashable (f (g a)) =>
Comp f g a -> Int
hash :: Comp f g a -> Int
$chash :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Hashable (f (g a)) =>
Comp f g a -> Int
hashWithSalt :: Int -> Comp f g a -> Int
$chashWithSalt :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Hashable (f (g a)) =>
Int -> Comp f g a -> Int
Hashable, [Comp f g a] -> Doc ann
Comp f g a -> Doc ann
(forall ann. Comp f g a -> Doc ann)
-> (forall ann. [Comp f g a] -> Doc ann) -> Pretty (Comp f g a)
forall ann. [Comp f g a] -> Doc ann
forall ann. Comp f g a -> Doc ann
forall a.
(forall ann. a -> Doc ann)
-> (forall ann. [a] -> Doc ann) -> Pretty a
forall j (f :: j -> Type) i (g :: i -> j) (a :: i) ann.
Pretty (f (g a)) =>
[Comp f g a] -> Doc ann
forall j (f :: j -> Type) i (g :: i -> j) (a :: i) ann.
Pretty (f (g a)) =>
Comp f g a -> Doc ann
prettyList :: [Comp f g a] -> Doc ann
$cprettyList :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i) ann.
Pretty (f (g a)) =>
[Comp f g a] -> Doc ann
pretty :: Comp f g a -> Doc ann
$cpretty :: forall j (f :: j -> Type) i (g :: i -> j) (a :: i) ann.
Pretty (f (g a)) =>
Comp f g a -> Doc ann
Pretty)

deriving instance (Functor f, Functor g) => Functor (Comp f g)
deriving instance (Foldable f, Foldable g) => Foldable (Comp f g)
deriving instance (Traversable f, Traversable g) => Traversable (Comp f g)

instance Lift (f (g a)) => Lift (Comp f g a) where
  lift :: Comp f g a -> Q Exp
lift = Q Exp -> Q Exp -> Q Exp
appE (Name -> Q Exp
conE 'Comp) (Q Exp -> Q Exp) -> (Comp f g a -> Q Exp) -> Comp f g a -> Q Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f (g a) -> Q Exp
forall t. Lift t => t -> Q Exp
lift (f (g a) -> Q Exp)
-> (Comp f g a -> f (g a)) -> Comp f g a -> Q Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Comp f g a -> f (g a)
forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Comp f g a -> f (g a)
getComp

-- | Wrap a result of 'fmap'
comp :: Functor f => (a -> g b) -> f a -> Comp f g b
comp :: (a -> g b) -> f a -> Comp f g b
comp a -> g b
f = f (g b) -> Comp f g b
forall j i (f :: j -> Type) (g :: i -> j) (a :: i).
f (g a) -> Comp f g a
Comp (f (g b) -> Comp f g b) -> (f a -> f (g b)) -> f a -> Comp 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 (Comp f g) where
  type Repr (Comp f g) x = f (Repr g x)
  _Wrapper :: Optic' p f (Comp f g v) (Repr (Comp 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 (Comp f g v) (f (Comp f g v)))
-> p (f (Repr g v)) (f (f (Repr g v)))
-> p (Comp f g v) (f (Comp 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 (Comp f g v) (f (Comp f g v)))
 -> p (f (Repr g v)) (f (f (Repr g v)))
 -> p (Comp f g v) (f (Comp f g v)))
-> ((g v -> Repr g v)
    -> (Repr g v -> g v)
    -> p (f (Repr g v)) (f (f (Repr g v)))
    -> p (Comp f g v) (f (Comp f g v)))
-> p (f (Repr g v)) (f (f (Repr g v)))
-> p (Comp f g v) (f (Comp f g v))
forall a b. (a -> b) -> a -> b
$ \g v -> Repr g v
f Repr g v -> g v
g -> (Comp f g v -> f (Repr g v))
-> (f (f (Repr g v)) -> f (Comp f g v))
-> p (f (Repr g v)) (f (f (Repr g v)))
-> p (Comp f g v) (f (Comp 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))
-> (Comp f g v -> f (g v)) -> Comp 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
.# Comp f g v -> f (g v)
forall j (f :: j -> Type) i (g :: i -> j) (a :: i).
Comp f g a -> f (g a)
getComp) ((f (Repr g v) -> Comp f g v) -> f (f (Repr g v)) -> f (Comp 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) -> Comp f g v
forall i (f :: Type -> Type) a (g :: i -> Type) (b :: i).
Functor f =>
(a -> g b) -> f a -> Comp 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