{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ScopedTypeVariables #-}
#if __GLASGOW_HASKELL__ >= 702
{-# LANGUAGE Trustworthy #-}
#endif

#if __GLASGOW_HASKELL__ >= 706
{-# LANGUAGE PolyKinds #-}
#endif

-----------------------------------------------------------------------------
-- |
-- Module      :  Data.Distributive
-- Copyright   :  (C) 2011-2016 Edward Kmett
-- License     :  BSD-style (see the file LICENSE)
--
-- Maintainer  :  Edward Kmett <ekmett@gmail.com>
-- Stability   :  provisional
-- Portability :  portable
--
----------------------------------------------------------------------------
module Data.Distributive
  ( Distributive(..)
  , cotraverse
  , comapM
  ) where

import Control.Applicative
import Control.Applicative.Backwards
import Control.Monad (liftM)
#if __GLASGOW_HASKELL__ < 707
import Control.Monad.Instances ()
#endif
import Control.Monad.Trans.Identity
import Control.Monad.Trans.Reader
import Data.Coerce
import Data.Functor.Compose
import Data.Functor.Identity
import Data.Functor.Product
import Data.Functor.Reverse
import qualified Data.Monoid as Monoid
import Data.Orphans ()

#if MIN_VERSION_base(4,4,0)
import Data.Complex
#endif
#if __GLASGOW_HASKELL__ >= 707 || defined(MIN_VERSION_tagged)
import Data.Proxy
#endif
#if __GLASGOW_HASKELL__ >= 800 || defined(MIN_VERSION_semigroups)
import qualified Data.Semigroup as Semigroup
#endif
#ifdef MIN_VERSION_tagged
import Data.Tagged
#endif
#if __GLASGOW_HASKELL__ >= 702
import GHC.Generics (U1(..), (:*:)(..), (:.:)(..), Par1(..), Rec1(..), M1(..))
#endif

#ifdef HLINT
{-# ANN module "hlint: ignore Use section" #-}
#endif

-- | This is the categorical dual of 'Traversable'.
--
-- Due to the lack of non-trivial comonoids in Haskell, we can restrict
-- ourselves to requiring a 'Functor' rather than
-- some Coapplicative class. Categorically every 'Distributive'
-- functor is actually a right adjoint, and so it must be 'Representable'
-- endofunctor and preserve all limits. This is a fancy way of saying it
-- is isomorphic to @(->) x@ for some x.
--
-- To be distributable a container will need to have a way to consistently
-- zip a potentially infinite number of copies of itself. This effectively
-- means that the holes in all values of that type, must have the same
-- cardinality, fixed sized vectors, infinite streams, functions, etc.
-- and no extra information to try to merge together.
--
class Functor g => Distributive g where
#if __GLASGOW_HASKELL__ >= 707
  {-# MINIMAL distribute | collect #-}
#endif
  -- | The dual of 'Data.Traversable.sequenceA'
  --
  -- >>> distribute [(+1),(+2)] 1
  -- [2,3]
  --
  -- @
  -- 'distribute' = 'collect' 'id'
  -- 'distribute' . 'distribute' = 'id'
  -- @
  distribute  :: Functor f => f (g a) -> g (f a)
  distribute  = (g a -> g a) -> f (g a) -> g (f a)
forall (g :: * -> *) (f :: * -> *) a b.
(Distributive g, Functor f) =>
(a -> g b) -> f a -> g (f b)
collect g a -> g a
forall a. a -> a
id

  -- |
  -- @
  -- 'collect' f = 'distribute' . 'fmap' f
  -- 'fmap' f = 'runIdentity' . 'collect' ('Identity' . f)
  -- 'fmap' 'distribute' . 'collect' f = 'getCompose' . 'collect' ('Compose' . f)
  -- @

  collect     :: Functor f => (a -> g b) -> f a -> g (f b)
  collect a -> g b
f   = f (g b) -> g (f b)
forall (g :: * -> *) (f :: * -> *) a.
(Distributive g, Functor f) =>
f (g a) -> g (f a)
distribute (f (g b) -> g (f b)) -> (f a -> f (g b)) -> f a -> g (f b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> g b) -> f a -> f (g b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> g b
f

  -- | The dual of 'Data.Traversable.sequence'
  --
  -- @
  -- 'distributeM' = 'fmap' 'unwrapMonad' . 'distribute' . 'WrapMonad'
  -- @
  distributeM :: Monad m => m (g a) -> g (m a)
  distributeM = (WrappedMonad m a -> m a) -> g (WrappedMonad m a) -> g (m a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap WrappedMonad m a -> m a
forall (m :: * -> *) a. WrappedMonad m a -> m a
unwrapMonad (g (WrappedMonad m a) -> g (m a))
-> (m (g a) -> g (WrappedMonad m a)) -> m (g a) -> g (m a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WrappedMonad m (g a) -> g (WrappedMonad m a)
forall (g :: * -> *) (f :: * -> *) a.
(Distributive g, Functor f) =>
f (g a) -> g (f a)
distribute (WrappedMonad m (g a) -> g (WrappedMonad m a))
-> (m (g a) -> WrappedMonad m (g a))
-> m (g a)
-> g (WrappedMonad m a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m (g a) -> WrappedMonad m (g a)
forall (m :: * -> *) a. m a -> WrappedMonad m a
WrapMonad

  -- |
  -- @
  -- 'collectM' = 'distributeM' . 'liftM' f
  -- @
  collectM    :: Monad m => (a -> g b) -> m a -> g (m b)
  collectM a -> g b
f  = m (g b) -> g (m b)
forall (g :: * -> *) (m :: * -> *) a.
(Distributive g, Monad m) =>
m (g a) -> g (m a)
distributeM (m (g b) -> g (m b)) -> (m a -> m (g b)) -> m a -> g (m b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> g b) -> m a -> m (g b)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM a -> g b
f

-- | The dual of 'Data.Traversable.traverse'
--
-- @
-- 'cotraverse' f = 'fmap' f . 'distribute'
-- @
cotraverse :: (Distributive g, Functor f) => (f a -> b) -> f (g a) -> g b
cotraverse :: (f a -> b) -> f (g a) -> g b
cotraverse f a -> b
f = (f a -> b) -> g (f a) -> g b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap f a -> b
f (g (f a) -> g b) -> (f (g a) -> g (f a)) -> f (g a) -> g b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f (g a) -> g (f a)
forall (g :: * -> *) (f :: * -> *) a.
(Distributive g, Functor f) =>
f (g a) -> g (f a)
distribute

-- | The dual of 'Data.Traversable.mapM'
--
-- @
-- 'comapM' f = 'fmap' f . 'distributeM'
-- @
comapM :: (Distributive g, Monad m) => (m a -> b) -> m (g a) -> g b
comapM :: (m a -> b) -> m (g a) -> g b
comapM m a -> b
f = (m a -> b) -> g (m a) -> g b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap m a -> b
f (g (m a) -> g b) -> (m (g a) -> g (m a)) -> m (g a) -> g b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m (g a) -> g (m a)
forall (g :: * -> *) (m :: * -> *) a.
(Distributive g, Monad m) =>
m (g a) -> g (m a)
distributeM

instance Distributive Identity where
  collect :: (a -> Identity b) -> f a -> Identity (f b)
collect = ((a -> b) -> f a -> f b)
-> (a -> Identity b) -> f a -> Identity (f b)
coerce ((a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap :: (a -> b) -> f a -> f b)
    :: forall a b f . Functor f => (a -> Identity b) -> f a -> Identity (f b)
  distribute :: f (Identity a) -> Identity (f a)
distribute = f a -> Identity (f a)
forall a. a -> Identity a
Identity (f a -> Identity (f a))
-> (f (Identity a) -> f a) -> f (Identity a) -> Identity (f a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Identity a -> a) -> f (Identity a) -> f a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Identity a -> a
forall a. Identity a -> a
runIdentity

#if __GLASGOW_HASKELL__ >= 707 || defined(MIN_VERSION_tagged)
instance Distributive Proxy where
  collect :: (a -> Proxy b) -> f a -> Proxy (f b)
collect a -> Proxy b
_ f a
_ = Proxy (f b)
forall k (t :: k). Proxy t
Proxy
  distribute :: f (Proxy a) -> Proxy (f a)
distribute f (Proxy a)
_ = Proxy (f a)
forall k (t :: k). Proxy t
Proxy
#endif

#if defined(MIN_VERSION_tagged)
instance Distributive (Tagged t) where
  collect :: (a -> Tagged t b) -> f a -> Tagged t (f b)
collect = ((a -> b) -> f a -> f b)
-> (a -> Tagged t b) -> f a -> Tagged t (f b)
coerce ((a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap :: (a -> b) -> f a -> f b)
    :: forall a b f . Functor f => (a -> Tagged t b) -> f a -> Tagged t (f b)
  distribute :: f (Tagged t a) -> Tagged t (f a)
distribute = f a -> Tagged t (f a)
forall k (s :: k) b. b -> Tagged s b
Tagged (f a -> Tagged t (f a))
-> (f (Tagged t a) -> f a) -> f (Tagged t a) -> Tagged t (f a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Tagged t a -> a) -> f (Tagged t a) -> f a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Tagged t a -> a
forall k (s :: k) b. Tagged s b -> b
unTagged
#endif

instance Distributive ((->)e) where
  distribute :: f (e -> a) -> e -> f a
distribute f (e -> a)
a e
e = ((e -> a) -> a) -> f (e -> a) -> f a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((e -> a) -> e -> a
forall a b. (a -> b) -> a -> b
$e
e) f (e -> a)
a
  collect :: (a -> e -> b) -> f a -> e -> f b
collect a -> e -> b
f f a
q e
e = (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> e -> b) -> e -> a -> b
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> e -> b
f e
e) f a
q

instance Distributive g => Distributive (ReaderT e g) where
  distribute :: f (ReaderT e g a) -> ReaderT e g (f a)
distribute f (ReaderT e g a)
a = (e -> g (f a)) -> ReaderT e g (f a)
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT ((e -> g (f a)) -> ReaderT e g (f a))
-> (e -> g (f a)) -> ReaderT e g (f a)
forall a b. (a -> b) -> a -> b
$ \e
e -> (ReaderT e g a -> g a) -> f (ReaderT e g a) -> g (f a)
forall (g :: * -> *) (f :: * -> *) a b.
(Distributive g, Functor f) =>
(a -> g b) -> f a -> g (f b)
collect ((ReaderT e g a -> e -> g a) -> e -> ReaderT e g a -> g a
forall a b c. (a -> b -> c) -> b -> a -> c
flip ReaderT e g a -> e -> g a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT e
e) f (ReaderT e g a)
a
  collect :: (a -> ReaderT e g b) -> f a -> ReaderT e g (f b)
collect a -> ReaderT e g b
f f a
x = (e -> g (f b)) -> ReaderT e g (f b)
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT ((e -> g (f b)) -> ReaderT e g (f b))
-> (e -> g (f b)) -> ReaderT e g (f b)
forall a b. (a -> b) -> a -> b
$ \e
e -> (a -> g b) -> f a -> g (f b)
forall (g :: * -> *) (f :: * -> *) a b.
(Distributive g, Functor f) =>
(a -> g b) -> f a -> g (f b)
collect (\a
a -> ReaderT e g b -> e -> g b
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (a -> ReaderT e g b
f a
a) e
e) f a
x

instance Distributive g => Distributive (IdentityT g) where
  collect :: (a -> IdentityT g b) -> f a -> IdentityT g (f b)
collect = ((a -> g b) -> f a -> g (f b))
-> (a -> IdentityT g b) -> f a -> IdentityT g (f b)
coerce ((a -> g b) -> f a -> g (f b)
forall (g :: * -> *) (f :: * -> *) a b.
(Distributive g, Functor f) =>
(a -> g b) -> f a -> g (f b)
collect :: (a -> g b) -> f a -> g (f b))
            :: forall a b f . Functor f => (a -> IdentityT g b) -> f a -> IdentityT g (f b)

instance (Distributive f, Distributive g) => Distributive (Compose f g) where
  distribute :: f (Compose f g a) -> Compose f g (f a)
distribute = f (g (f a)) -> Compose f g (f a)
forall k k1 (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose (f (g (f a)) -> Compose f g (f a))
-> (f (Compose f g a) -> f (g (f a)))
-> f (Compose f g a)
-> Compose f g (f a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (f (g a) -> g (f a)) -> f (f (g a)) -> f (g (f a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap f (g a) -> g (f a)
forall (g :: * -> *) (f :: * -> *) a.
(Distributive g, Functor f) =>
f (g a) -> g (f a)
distribute (f (f (g a)) -> f (g (f a)))
-> (f (Compose f g a) -> f (f (g a)))
-> f (Compose f g a)
-> f (g (f a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Compose f g a -> f (g a)) -> f (Compose f g a) -> f (f (g a))
forall (g :: * -> *) (f :: * -> *) a b.
(Distributive g, Functor f) =>
(a -> g b) -> f a -> g (f b)
collect Compose f g a -> f (g a)
forall k1 (f :: k1 -> *) k2 (g :: k2 -> k1) (a :: k2).
Compose f g a -> f (g a)
getCompose
  collect :: (a -> Compose f g b) -> f a -> Compose f g (f b)
collect a -> Compose f g b
f = f (g (f b)) -> Compose f g (f b)
forall k k1 (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose (f (g (f b)) -> Compose f g (f b))
-> (f a -> f (g (f b))) -> f a -> Compose f g (f b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (f (g b) -> g (f b)) -> f (f (g b)) -> f (g (f b))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap f (g b) -> g (f b)
forall (g :: * -> *) (f :: * -> *) a.
(Distributive g, Functor f) =>
f (g a) -> g (f a)
distribute (f (f (g b)) -> f (g (f b)))
-> (f a -> f (f (g b))) -> f a -> f (g (f b))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> f (g b)) -> f a -> f (f (g b))
forall (g :: * -> *) (f :: * -> *) a b.
(Distributive g, Functor f) =>
(a -> g b) -> f a -> g (f b)
collect ((a -> Compose f g b) -> a -> f (g b)
coerce a -> Compose f g b
f)

instance (Distributive f, Distributive g) => Distributive (Product f g) where
  -- It might be tempting to write a 'collect' implementation that
  -- composes the passed function with fstP and sndP. This could be bad,
  -- because it would lead to the passed function being evaluated twice
  -- for each element of the underlying functor.
  distribute :: f (Product f g a) -> Product f g (f a)
distribute f (Product f g a)
wp = f (f a) -> g (f a) -> Product f g (f a)
forall k (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product f g a
Pair ((Product f g a -> f a) -> f (Product f g a) -> f (f a)
forall (g :: * -> *) (f :: * -> *) a b.
(Distributive g, Functor f) =>
(a -> g b) -> f a -> g (f b)
collect Product f g a -> f a
forall k (f :: k -> *) (g :: k -> *) (a :: k). Product f g a -> f a
fstP f (Product f g a)
wp) ((Product f g a -> g a) -> f (Product f g a) -> g (f a)
forall (g :: * -> *) (f :: * -> *) a b.
(Distributive g, Functor f) =>
(a -> g b) -> f a -> g (f b)
collect Product f g a -> g a
forall k (f :: k -> *) (g :: k -> *) (a :: k). Product f g a -> g a
sndP f (Product f g a)
wp) where
    fstP :: Product f g a -> f a
fstP (Pair f a
a g a
_) = f a
a
    sndP :: Product f g a -> g a
sndP (Pair f a
_ g a
b) = g a
b


instance Distributive f => Distributive (Backwards f) where
  distribute :: f (Backwards f a) -> Backwards f (f a)
distribute = f (f a) -> Backwards f (f a)
forall k (f :: k -> *) (a :: k). f a -> Backwards f a
Backwards (f (f a) -> Backwards f (f a))
-> (f (Backwards f a) -> f (f a))
-> f (Backwards f a)
-> Backwards f (f a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Backwards f a -> f a) -> f (Backwards f a) -> f (f a)
forall (g :: * -> *) (f :: * -> *) a b.
(Distributive g, Functor f) =>
(a -> g b) -> f a -> g (f b)
collect Backwards f a -> f a
forall k (f :: k -> *) (a :: k). Backwards f a -> f a
forwards
  collect :: (a -> Backwards f b) -> f a -> Backwards f (f b)
collect = ((a -> f b) -> g a -> f (g b))
-> (a -> Backwards f b) -> g a -> Backwards f (g b)
coerce ((a -> f b) -> g a -> f (g b)
forall (g :: * -> *) (f :: * -> *) a b.
(Distributive g, Functor f) =>
(a -> g b) -> f a -> g (f b)
collect :: (a -> f b) -> g a -> f (g b))
    :: forall g a b . Functor g
    => (a -> Backwards f b) -> g a -> Backwards f (g b)

instance Distributive f => Distributive (Reverse f) where
  distribute :: f (Reverse f a) -> Reverse f (f a)
distribute = f (f a) -> Reverse f (f a)
forall k (f :: k -> *) (a :: k). f a -> Reverse f a
Reverse (f (f a) -> Reverse f (f a))
-> (f (Reverse f a) -> f (f a))
-> f (Reverse f a)
-> Reverse f (f a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Reverse f a -> f a) -> f (Reverse f a) -> f (f a)
forall (g :: * -> *) (f :: * -> *) a b.
(Distributive g, Functor f) =>
(a -> g b) -> f a -> g (f b)
collect Reverse f a -> f a
forall k (f :: k -> *) (a :: k). Reverse f a -> f a
getReverse
  collect :: (a -> Reverse f b) -> f a -> Reverse f (f b)
collect = ((a -> f b) -> g a -> f (g b))
-> (a -> Reverse f b) -> g a -> Reverse f (g b)
coerce ((a -> f b) -> g a -> f (g b)
forall (g :: * -> *) (f :: * -> *) a b.
(Distributive g, Functor f) =>
(a -> g b) -> f a -> g (f b)
collect :: (a -> f b) -> g a -> f (g b))
    :: forall g a b . Functor g
    => (a -> Reverse f b) -> g a -> Reverse f (g b)

instance Distributive Monoid.Dual where
  collect :: (a -> Dual b) -> f a -> Dual (f b)
collect = ((a -> b) -> f a -> f b) -> (a -> Dual b) -> f a -> Dual (f b)
coerce ((a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap :: (a -> b) -> f a -> f b)
    :: forall f a b . Functor f
    => (a -> Monoid.Dual b) -> f a -> Monoid.Dual (f b)
  distribute :: f (Dual a) -> Dual (f a)
distribute = f a -> Dual (f a)
forall a. a -> Dual a
Monoid.Dual (f a -> Dual (f a))
-> (f (Dual a) -> f a) -> f (Dual a) -> Dual (f a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Dual a -> a) -> f (Dual a) -> f a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Dual a -> a
forall a. Dual a -> a
Monoid.getDual

instance Distributive Monoid.Product where
  collect :: (a -> Product b) -> f a -> Product (f b)
collect = ((a -> b) -> f a -> f b)
-> (a -> Product b) -> f a -> Product (f b)
coerce ((a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap :: (a -> b) -> f a -> f b)
    :: forall f a b . Functor f
    => (a -> Monoid.Product b) -> f a -> Monoid.Product (f b)
  distribute :: f (Product a) -> Product (f a)
distribute = f a -> Product (f a)
forall a. a -> Product a
Monoid.Product (f a -> Product (f a))
-> (f (Product a) -> f a) -> f (Product a) -> Product (f a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Product a -> a) -> f (Product a) -> f a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Product a -> a
forall a. Product a -> a
Monoid.getProduct

instance Distributive Monoid.Sum where
  collect :: (a -> Sum b) -> f a -> Sum (f b)
collect = ((a -> b) -> f a -> f b) -> (a -> Sum b) -> f a -> Sum (f b)
coerce ((a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap :: (a -> b) -> f a -> f b)
    :: forall f a b . Functor f
    => (a -> Monoid.Sum b) -> f a -> Monoid.Sum (f b)
  distribute :: f (Sum a) -> Sum (f a)
distribute = f a -> Sum (f a)
forall a. a -> Sum a
Monoid.Sum (f a -> Sum (f a)) -> (f (Sum a) -> f a) -> f (Sum a) -> Sum (f a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Sum a -> a) -> f (Sum a) -> f a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Sum a -> a
forall a. Sum a -> a
Monoid.getSum

#if __GLASGOW_HASKELL__ >= 800 || defined(MIN_VERSION_semigroups)
instance Distributive Semigroup.Min where
  collect :: (a -> Min b) -> f a -> Min (f b)
collect = ((a -> b) -> f a -> f b) -> (a -> Min b) -> f a -> Min (f b)
coerce ((a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap :: (a -> b) -> f a -> f b)
    :: forall f a b . Functor f
    => (a -> Semigroup.Min b) -> f a -> Semigroup.Min (f b)
  distribute :: f (Min a) -> Min (f a)
distribute = f a -> Min (f a)
forall a. a -> Min a
Semigroup.Min (f a -> Min (f a)) -> (f (Min a) -> f a) -> f (Min a) -> Min (f a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Min a -> a) -> f (Min a) -> f a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Min a -> a
forall a. Min a -> a
Semigroup.getMin

instance Distributive Semigroup.Max where
  collect :: (a -> Max b) -> f a -> Max (f b)
collect = ((a -> b) -> f a -> f b) -> (a -> Max b) -> f a -> Max (f b)
coerce ((a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap :: (a -> b) -> f a -> f b)
    :: forall f a b . Functor f
    => (a -> Semigroup.Max b) -> f a -> Semigroup.Max (f b)
  distribute :: f (Max a) -> Max (f a)
distribute = f a -> Max (f a)
forall a. a -> Max a
Semigroup.Max (f a -> Max (f a)) -> (f (Max a) -> f a) -> f (Max a) -> Max (f a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Max a -> a) -> f (Max a) -> f a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Max a -> a
forall a. Max a -> a
Semigroup.getMax

instance Distributive Semigroup.First where
  collect :: (a -> First b) -> f a -> First (f b)
collect = ((a -> b) -> f a -> f b) -> (a -> First b) -> f a -> First (f b)
coerce ((a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap :: (a -> b) -> f a -> f b)
    :: forall f a b . Functor f
    => (a -> Semigroup.First b) -> f a -> Semigroup.First (f b)
  distribute :: f (First a) -> First (f a)
distribute = f a -> First (f a)
forall a. a -> First a
Semigroup.First (f a -> First (f a))
-> (f (First a) -> f a) -> f (First a) -> First (f a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (First a -> a) -> f (First a) -> f a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap First a -> a
forall a. First a -> a
Semigroup.getFirst

instance Distributive Semigroup.Last where
  collect :: (a -> Last b) -> f a -> Last (f b)
collect = ((a -> b) -> f a -> f b) -> (a -> Last b) -> f a -> Last (f b)
coerce ((a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap :: (a -> b) -> f a -> f b)
    :: forall f a b . Functor f
    => (a -> Semigroup.Last b) -> f a -> Semigroup.Last (f b)
  distribute :: f (Last a) -> Last (f a)
distribute = f a -> Last (f a)
forall a. a -> Last a
Semigroup.Last (f a -> Last (f a))
-> (f (Last a) -> f a) -> f (Last a) -> Last (f a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Last a -> a) -> f (Last a) -> f a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Last a -> a
forall a. Last a -> a
Semigroup.getLast
#endif

#if MIN_VERSION_base(4,4,0)
instance Distributive Complex where
  distribute :: f (Complex a) -> Complex (f a)
distribute f (Complex a)
wc = (Complex a -> a) -> f (Complex a) -> f a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Complex a -> a
forall a. Complex a -> a
realP f (Complex a)
wc f a -> f a -> Complex (f a)
forall a. a -> a -> Complex a
:+ (Complex a -> a) -> f (Complex a) -> f a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Complex a -> a
forall a. Complex a -> a
imagP f (Complex a)
wc where
    -- Redefine realPart and imagPart to avoid incurring redundant RealFloat
    -- constraints on older versions of base
    realP :: Complex a -> a
realP (a
r :+ a
_) = a
r
    imagP :: Complex a -> a
imagP (a
_ :+ a
i) = a
i
#endif

instance (Distributive m, Monad m) => Distributive (WrappedMonad m) where
  collect :: (a -> WrappedMonad m b) -> f a -> WrappedMonad m (f b)
collect a -> WrappedMonad m b
f = m (f b) -> WrappedMonad m (f b)
forall (m :: * -> *) a. m a -> WrappedMonad m a
WrapMonad (m (f b) -> WrappedMonad m (f b))
-> (f a -> m (f b)) -> f a -> WrappedMonad m (f b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> m b) -> f a -> m (f b)
forall (g :: * -> *) (f :: * -> *) a b.
(Distributive g, Functor f) =>
(a -> g b) -> f a -> g (f b)
collect ((a -> WrappedMonad m b) -> a -> m b
coerce a -> WrappedMonad m b
f)

#if __GLASGOW_HASKELL__ >= 702
instance Distributive U1 where
  distribute :: f (U1 a) -> U1 (f a)
distribute f (U1 a)
_ = U1 (f a)
forall k (p :: k). U1 p
U1

instance (Distributive a, Distributive b) => Distributive (a :*: b) where
  -- It might be tempting to write a 'collect' implementation that
  -- composes the passed function with fstP and sndP. This could be bad,
  -- because it would lead to the passed function being evaluated twice
  -- for each element of the underlying functor.
  distribute :: f ((:*:) a b a) -> (:*:) a b (f a)
distribute f ((:*:) a b a)
f = ((:*:) a b a -> a a) -> f ((:*:) a b a) -> a (f a)
forall (g :: * -> *) (f :: * -> *) a b.
(Distributive g, Functor f) =>
(a -> g b) -> f a -> g (f b)
collect (:*:) a b a -> a a
forall k (f :: k -> *) (g :: k -> *) (p :: k). (:*:) f g p -> f p
fstP f ((:*:) a b a)
f a (f a) -> b (f a) -> (:*:) a b (f a)
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: ((:*:) a b a -> b a) -> f ((:*:) a b a) -> b (f a)
forall (g :: * -> *) (f :: * -> *) a b.
(Distributive g, Functor f) =>
(a -> g b) -> f a -> g (f b)
collect (:*:) a b a -> b a
forall k (f :: k -> *) (g :: k -> *) (p :: k). (:*:) f g p -> g p
sndP f ((:*:) a b a)
f where
    fstP :: (:*:) f g p -> f p
fstP (f p
l :*: g p
_) = f p
l
    sndP :: (:*:) f g p -> g p
sndP (f p
_ :*: g p
r) = g p
r

instance (Distributive a, Distributive b) => Distributive (a :.: b) where
  distribute :: f ((:.:) a b a) -> (:.:) a b (f a)
distribute = a (b (f a)) -> (:.:) a b (f a)
forall k2 k1 (f :: k2 -> *) (g :: k1 -> k2) (p :: k1).
f (g p) -> (:.:) f g p
Comp1 (a (b (f a)) -> (:.:) a b (f a))
-> (f ((:.:) a b a) -> a (b (f a)))
-> f ((:.:) a b a)
-> (:.:) a b (f a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (f (b a) -> b (f a)) -> a (f (b a)) -> a (b (f a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap f (b a) -> b (f a)
forall (g :: * -> *) (f :: * -> *) a.
(Distributive g, Functor f) =>
f (g a) -> g (f a)
distribute (a (f (b a)) -> a (b (f a)))
-> (f ((:.:) a b a) -> a (f (b a)))
-> f ((:.:) a b a)
-> a (b (f a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((:.:) a b a -> a (b a)) -> f ((:.:) a b a) -> a (f (b a))
forall (g :: * -> *) (f :: * -> *) a b.
(Distributive g, Functor f) =>
(a -> g b) -> f a -> g (f b)
collect (:.:) a b a -> a (b a)
forall k2 (f :: k2 -> *) k1 (g :: k1 -> k2) (p :: k1).
(:.:) f g p -> f (g p)
unComp1
  collect :: (a -> (:.:) a b b) -> f a -> (:.:) a b (f b)
collect a -> (:.:) a b b
f = a (b (f b)) -> (:.:) a b (f b)
forall k2 k1 (f :: k2 -> *) (g :: k1 -> k2) (p :: k1).
f (g p) -> (:.:) f g p
Comp1 (a (b (f b)) -> (:.:) a b (f b))
-> (f a -> a (b (f b))) -> f a -> (:.:) a b (f b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (f (b b) -> b (f b)) -> a (f (b b)) -> a (b (f b))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap f (b b) -> b (f b)
forall (g :: * -> *) (f :: * -> *) a.
(Distributive g, Functor f) =>
f (g a) -> g (f a)
distribute (a (f (b b)) -> a (b (f b)))
-> (f a -> a (f (b b))) -> f a -> a (b (f b))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> a (b b)) -> f a -> a (f (b b))
forall (g :: * -> *) (f :: * -> *) a b.
(Distributive g, Functor f) =>
(a -> g b) -> f a -> g (f b)
collect ((a -> (:.:) a b b) -> a -> a (b b)
coerce a -> (:.:) a b b
f)

instance Distributive Par1 where
  distribute :: f (Par1 a) -> Par1 (f a)
distribute = f a -> Par1 (f a)
forall p. p -> Par1 p
Par1 (f a -> Par1 (f a))
-> (f (Par1 a) -> f a) -> f (Par1 a) -> Par1 (f a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Par1 a -> a) -> f (Par1 a) -> f a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Par1 a -> a
forall p. Par1 p -> p
unPar1
  collect :: (a -> Par1 b) -> f a -> Par1 (f b)
collect = ((a -> b) -> f a -> f b) -> (a -> Par1 b) -> f a -> Par1 (f b)
coerce ((a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap :: (a -> b) -> f a -> f b)
    :: forall f a b . Functor f => (a -> Par1 b) -> f a -> Par1 (f b)

instance Distributive f => Distributive (Rec1 f) where
  distribute :: f (Rec1 f a) -> Rec1 f (f a)
distribute = f (f a) -> Rec1 f (f a)
forall k (f :: k -> *) (p :: k). f p -> Rec1 f p
Rec1 (f (f a) -> Rec1 f (f a))
-> (f (Rec1 f a) -> f (f a)) -> f (Rec1 f a) -> Rec1 f (f a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Rec1 f a -> f a) -> f (Rec1 f a) -> f (f a)
forall (g :: * -> *) (f :: * -> *) a b.
(Distributive g, Functor f) =>
(a -> g b) -> f a -> g (f b)
collect Rec1 f a -> f a
forall k (f :: k -> *) (p :: k). Rec1 f p -> f p
unRec1
  collect :: (a -> Rec1 f b) -> f a -> Rec1 f (f b)
collect = ((a -> f b) -> g a -> f (g b))
-> (a -> Rec1 f b) -> g a -> Rec1 f (g b)
coerce ((a -> f b) -> g a -> f (g b)
forall (g :: * -> *) (f :: * -> *) a b.
(Distributive g, Functor f) =>
(a -> g b) -> f a -> g (f b)
collect :: (a -> f b) -> g a -> f (g b))
    :: forall g a b . Functor g
    => (a -> Rec1 f b) -> g a -> Rec1 f (g b)

instance Distributive f => Distributive (M1 i c f) where
  distribute :: f (M1 i c f a) -> M1 i c f (f a)
distribute = f (f a) -> M1 i c f (f a)
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (f (f a) -> M1 i c f (f a))
-> (f (M1 i c f a) -> f (f a)) -> f (M1 i c f a) -> M1 i c f (f a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (M1 i c f a -> f a) -> f (M1 i c f a) -> f (f a)
forall (g :: * -> *) (f :: * -> *) a b.
(Distributive g, Functor f) =>
(a -> g b) -> f a -> g (f b)
collect M1 i c f a -> f a
forall i (c :: Meta) k (f :: k -> *) (p :: k). M1 i c f p -> f p
unM1
  collect :: (a -> M1 i c f b) -> f a -> M1 i c f (f b)
collect = ((a -> f b) -> g a -> f (g b))
-> (a -> M1 i c f b) -> g a -> M1 i c f (g b)
coerce ((a -> f b) -> g a -> f (g b)
forall (g :: * -> *) (f :: * -> *) a b.
(Distributive g, Functor f) =>
(a -> g b) -> f a -> g (f b)
collect :: (a -> f b) -> g a -> f (g b))
    :: forall g a b . Functor g
    => (a -> M1 i c f b) -> g a -> M1 i c f (g b)
#endif