{-# 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))
-> p (Repr h v) (f (Repr h v))
-> p (h v) (f (h v))
forall a b c d. (a -> b) -> (c -> d) -> p b c -> p a d
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 (v :: k). 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 a b. (a -> b) -> f a -> f b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap Repr h v -> h v
forall (v :: k). 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)
forall (f :: Type -> Type) (p :: Type -> Type -> Type) (v :: k).
(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)
forall (f :: Type -> Type) (p :: Type -> Type -> Type) (v :: k).
(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 :: forall {k} (f :: Type -> Type) (p :: Type -> Type -> Type)
       (h :: k -> Type) (proxy :: k -> Type) (v :: k).
(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)
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)
forall (f :: Type -> Type) (p :: Type -> Type -> Type) (v :: k).
(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 :: forall v. Identity v -> Repr Identity v
unwrap = Identity v -> v
Identity v -> Repr Identity v
forall a. Identity a -> a
runIdentity
  {-# INLINE unwrap #-}
  wrap :: forall v. Repr Identity v -> Identity v
wrap = v -> Identity v
Repr Identity v -> Identity v
forall a. a -> Identity a
Identity
  {-# INLINE wrap #-}

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

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

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

type Comp = Compose

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


getComp :: Compose f g a -> f (g a)
getComp :: forall {k} {k1} (f :: k -> Type) (g :: k1 -> k) (a :: k1).
Compose f g a -> f (g a)
getComp = Compose f g a -> f (g a)
forall {k} {k1} (f :: k -> Type) (g :: k1 -> k) (a :: k1).
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 :: forall {k1} (f :: Type -> Type) a (g :: k1 -> Type) (b :: k1).
Functor f =>
(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 a b c (q :: Type -> Type -> Type).
Coercible c b =>
q b c -> (a -> b) -> a -> c
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 a b. (a -> b) -> f a -> f 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 :: forall (f :: Type -> Type) (p :: Type -> Type -> Type) (v :: k).
(Functor f, Profunctor p) =>
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)
    -> Optic' p f (Compose f g v) (Repr (Compose f g) v))
-> Optic' p f (Compose f g v) (Repr (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)
forall (f :: Type -> Type) (p :: Type -> Type -> Type) (v :: k).
(Functor f, Profunctor p) =>
Optic' p f (g v) (Repr g v)
_Wrapper (((g v -> Repr g v)
  -> (Repr g v -> g v)
  -> Optic' p f (Compose f g v) (Repr (Compose f g) v))
 -> Optic' p f (Compose f g v) (Repr (Compose f g) v))
-> ((g v -> Repr g v)
    -> (Repr g v -> g v)
    -> Optic' p f (Compose f g v) (Repr (Compose f g) v))
-> Optic' p f (Compose f g v) (Repr (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 a b c d. (a -> b) -> (c -> d) -> p b c -> p a d
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 a b. (a -> b) -> f a -> f b
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 a b c (q :: Type -> Type -> Type).
Coercible b a =>
(b -> c) -> q a b -> a -> c
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 {k} {k1} (f :: k -> Type) (g :: k1 -> k) (a :: k1).
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 a b. (a -> b) -> f a -> f b
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 :: forall (v :: k). Repr (Const a) v -> Const a v
wrap = a -> Const a v
Repr (Const a) v -> Const a v
forall {k} a (b :: k). a -> Const a b
Const
  {-# INLINE wrap #-}
  unwrap :: forall (v :: k). Const a v -> Repr (Const a) v
unwrap = Const a v -> a
Const a v -> Repr (Const a) v
forall {k} a (b :: k). Const a b -> a
getConst
  {-# INLINE unwrap #-}

instance Wrapper Proxy where
  type Repr Proxy x = ()
  wrap :: forall (v :: k). Repr Proxy v -> Proxy v
wrap Repr Proxy v
_ = Proxy v
forall {k} (t :: k). Proxy t
Proxy
  {-# INLINE wrap #-}
  unwrap :: forall (v :: k). 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
$cshowsPrec :: forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
(Show (f a), Show (g a)) =>
Int -> Prod f g a -> ShowS
showsPrec :: Int -> Prod f g a -> ShowS
$cshow :: forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
(Show (f a), Show (g a)) =>
Prod f g a -> String
show :: Prod f g a -> String
$cshowList :: forall k (f :: k -> Type) (g :: k -> Type) (a :: k).
(Show (f a), Show (g a)) =>
[Prod f g a] -> ShowS
showList :: [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
$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
/= :: 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
$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
compare :: Prod f g a -> Prod f g a -> Ordering
$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
>= :: Prod f g a -> Prod f g a -> Bool
$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
max :: 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
min :: Prod f g a -> Prod f g a -> 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
$cfrom :: forall k (f :: k -> Type) (g :: k -> Type) (a :: k) x.
Prod f g a -> Rep (Prod f g a) x
from :: forall 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
to :: forall x. Rep (Prod f g a) x -> Prod f g a
Generic, (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
$cfmap :: forall (f :: Type -> Type) (g :: Type -> Type) a b.
(Functor f, Functor g) =>
(a -> b) -> Prod f g a -> Prod f g b
fmap :: forall a b. (a -> b) -> Prod f g a -> Prod f g b
$c<$ :: forall (f :: Type -> Type) (g :: Type -> Type) a b.
(Functor f, Functor g) =>
a -> Prod f g b -> Prod f g a
<$ :: forall a b. a -> Prod f g b -> Prod f g a
Functor, (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
$cfold :: forall (f :: Type -> Type) (g :: Type -> Type) m.
(Foldable f, Foldable g, Monoid m) =>
Prod f g m -> m
fold :: forall m. Monoid m => Prod f g m -> 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 :: forall m a. Monoid m => (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' :: forall m a. Monoid m => (a -> m) -> Prod f g a -> m
$cfoldr :: forall (f :: Type -> Type) (g :: Type -> Type) a b.
(Foldable f, Foldable g) =>
(a -> b -> b) -> b -> Prod f g a -> b
foldr :: forall a b. (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' :: forall a b. (a -> b -> 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 :: forall b a. (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' :: forall b a. (b -> a -> b) -> b -> Prod f g a -> b
$cfoldr1 :: forall (f :: Type -> Type) (g :: Type -> Type) a.
(Foldable f, Foldable g) =>
(a -> a -> a) -> Prod f g a -> a
foldr1 :: forall a. (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
foldl1 :: forall a. (a -> a -> a) -> Prod f g a -> a
$ctoList :: forall (f :: Type -> Type) (g :: Type -> Type) a.
(Foldable f, Foldable g) =>
Prod f g a -> [a]
toList :: forall a. Prod f g a -> [a]
$cnull :: forall (f :: Type -> Type) (g :: Type -> Type) a.
(Foldable f, Foldable g) =>
Prod f g a -> Bool
null :: forall a. Prod f g a -> Bool
$clength :: forall (f :: Type -> Type) (g :: Type -> Type) a.
(Foldable f, Foldable g) =>
Prod f g a -> Int
length :: forall a. Prod f g a -> Int
$celem :: forall (f :: Type -> Type) (g :: Type -> Type) a.
(Foldable f, Foldable g, Eq a) =>
a -> Prod f g a -> Bool
elem :: forall a. Eq a => a -> Prod f g a -> Bool
$cmaximum :: forall (f :: Type -> Type) (g :: Type -> Type) a.
(Foldable f, Foldable g, Ord a) =>
Prod f g a -> a
maximum :: forall a. Ord a => 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
minimum :: forall a. Ord a => 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
sum :: forall a. Num a => 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
product :: forall a. Num a => Prod f g a -> a
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)
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)
$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)
traverse :: forall (f :: Type -> Type) a b.
Applicative f =>
(a -> f b) -> Prod f g a -> f (Prod f g b)
$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)
sequenceA :: forall (f :: Type -> Type) a.
Applicative f =>
Prod f g (f a) -> f (Prod f g a)
$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)
mapM :: forall (m :: Type -> Type) a b.
Monad m =>
(a -> m b) -> Prod f g a -> m (Prod f g b)
$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)
sequence :: forall (m :: Type -> Type) a.
Monad m =>
Prod f g (m a) -> m (Prod f g a)
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 :: forall (v :: k). Prod f g v -> Repr (Prod f g) v
unwrap (Prod f v
f g v
g) = (f v -> Repr f v
forall (v :: k). 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 (v :: k). 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 :: forall (v :: k). Repr (Prod f g) v -> Prod f g v
wrap (Repr f v
f, Repr g v
g) = Repr f v -> f v
forall (v :: k). 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 (v :: k). 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 a b. Gen (a -> b) -> Gen a -> Gen b
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