{-|
Module      : Data.Traversable.Homogeneous
Description : homogeneous
Copyright   : (C) 2026 - Eitan Chatav
License     : BSD-style (see the file LICENSE)
Maintainer  : Eitan Chatav <eitan.chatav@gmail.com>
Stability   : provisional
Portability : non-portable
-}

module Data.Traversable.Homogeneous
  ( -- * Homogeneous
    Homogeneous (..)
  ) where

import Control.Applicative
import Control.Lens hiding (chosen)
import Control.Lens.PartialIso
import Data.Complex
import Data.Functor.Compose
import qualified Data.Functor.Product as Functor
import qualified Data.Functor.Sum as Functor
import qualified Data.Monoid as Monoid
import Data.Profunctor.Monoidal
import Data.Proxy
import Data.Sequence (Seq)
import Data.Tagged
import Data.Tree (Tree (..))
import Data.Vector (Vector)
import Data.Void
import GHC.Generics

import Data.Profunctor.Distributor

{- | A class of `Homogeneous`
countable sums of countable products.
-}
class Traversable t => Homogeneous t where
  {- | Sequences actions `homogeneously`.

  prop> homogeneously @Maybe = optionalP
  prop> homogeneously @[] = manyP

  Any `Traversable` & `Data.Distributive.Distributive` countable product
  can be given a default implementation for the `homogeneously` method
  with `ditraverse`.

  prop> homogeneously = ditraverse

  And any user-defined homogeneous algebraic datatype has
  a default instance for `Homogeneous`, by deriving `Generic1`.
  -}
  homogeneously :: Distributor p => p a b -> p (t a) (t b)
  default homogeneously
    :: (Generic1 t, Homogeneous (Rep1 t), Distributor p)
    => p a b -> p (t a) (t b)
  homogeneously = (t a -> Rep1 t a)
-> (Rep1 t b -> t b) -> p (Rep1 t a) (Rep1 t b) -> p (t a) (t b)
forall a b c d. (a -> b) -> (c -> d) -> p b c -> p a d
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap t a -> Rep1 t a
forall a. t a -> Rep1 t a
forall k (f :: k -> *) (a :: k). Generic1 f => f a -> Rep1 f a
from1 Rep1 t b -> t b
forall a. Rep1 t a -> t a
forall k (f :: k -> *) (a :: k). Generic1 f => Rep1 f a -> f a
to1 (p (Rep1 t a) (Rep1 t b) -> p (t a) (t b))
-> (p a b -> p (Rep1 t a) (Rep1 t b)) -> p a b -> p (t a) (t b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. p a b -> p (Rep1 t a) (Rep1 t b)
forall (t :: * -> *) (p :: * -> * -> *) a b.
(Homogeneous t, Distributor p) =>
p a b -> p (t a) (t b)
forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (Rep1 t a) (Rep1 t b)
homogeneously
instance Homogeneous Par1 where
  homogeneously :: forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (Par1 a) (Par1 b)
homogeneously = (Par1 a -> a) -> (b -> Par1 b) -> p a b -> p (Par1 a) (Par1 b)
forall a b c d. (a -> b) -> (c -> d) -> p b c -> p a d
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap Par1 a -> a
forall p. Par1 p -> p
unPar1 b -> Par1 b
forall p. p -> Par1 p
Par1
instance Homogeneous Identity where
  homogeneously :: forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (Identity a) (Identity b)
homogeneously = (Identity a -> a)
-> (b -> Identity b) -> p a b -> p (Identity a) (Identity b)
forall a b c d. (a -> b) -> (c -> d) -> p b c -> p a d
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap Identity a -> a
forall a. Identity a -> a
runIdentity b -> Identity b
forall a. a -> Identity a
Identity
instance Homogeneous Monoid.Dual where
  homogeneously :: forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (Dual a) (Dual b)
homogeneously = (Dual a -> a) -> (b -> Dual b) -> p a b -> p (Dual a) (Dual b)
forall a b c d. (a -> b) -> (c -> d) -> p b c -> p a d
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap Dual a -> a
forall a. Dual a -> a
Monoid.getDual b -> Dual b
forall a. a -> Dual a
Monoid.Dual
instance Homogeneous Monoid.Product where
  homogeneously :: forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (Product a) (Product b)
homogeneously = (Product a -> a)
-> (b -> Product b) -> p a b -> p (Product a) (Product b)
forall a b c d. (a -> b) -> (c -> d) -> p b c -> p a d
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap Product a -> a
forall a. Product a -> a
Monoid.getProduct b -> Product b
forall a. a -> Product a
Monoid.Product
instance Homogeneous Monoid.Sum where
  homogeneously :: forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (Sum a) (Sum b)
homogeneously = (Sum a -> a) -> (b -> Sum b) -> p a b -> p (Sum a) (Sum b)
forall a b c d. (a -> b) -> (c -> d) -> p b c -> p a d
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap Sum a -> a
forall a. Sum a -> a
Monoid.getSum b -> Sum b
forall a. a -> Sum a
Monoid.Sum
instance Homogeneous (Tagged s) where
  homogeneously :: forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (Tagged s a) (Tagged s b)
homogeneously = (Tagged s a -> a)
-> (b -> Tagged s b) -> p a b -> p (Tagged s a) (Tagged s b)
forall a b c d. (a -> b) -> (c -> d) -> p b c -> p a d
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap Tagged s a -> a
forall {k} (s :: k) b. Tagged s b -> b
unTagged b -> Tagged s b
forall {k} (s :: k) b. b -> Tagged s b
Tagged
instance Homogeneous U1 where
  homogeneously :: forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (U1 a) (U1 b)
homogeneously p a b
_ = U1 b -> p (U1 a) (U1 b)
forall a. a -> p (U1 a) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure U1 b
forall k (p :: k). U1 p
U1
instance Homogeneous (K1 i ()) where
  homogeneously :: forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (K1 i () a) (K1 i () b)
homogeneously p a b
_ = K1 i () b -> p (K1 i () a) (K1 i () b)
forall a. a -> p (K1 i () a) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (() -> K1 i () b
forall k i c (p :: k). c -> K1 i c p
K1 ())
instance Homogeneous (Const ()) where
  homogeneously :: forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (Const () a) (Const () b)
homogeneously p a b
_ = Const () b -> p (Const () a) (Const () b)
forall a. a -> p (Const () a) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (() -> Const () b
forall {k} a (b :: k). a -> Const a b
Const ())
instance Homogeneous Proxy where
  homogeneously :: forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (Proxy a) (Proxy b)
homogeneously p a b
_ = Proxy b -> p (Proxy a) (Proxy b)
forall a. a -> p (Proxy a) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Proxy b
forall {k} (t :: k). Proxy t
Proxy
instance (Homogeneous s, Homogeneous t)
  => Homogeneous (s :.: t) where
    homogeneously :: forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p ((:.:) s t a) ((:.:) s t b)
homogeneously
      = ((:.:) s t a -> s (t a))
-> (s (t b) -> (:.:) s t b)
-> p (s (t a)) (s (t b))
-> p ((:.:) s t a) ((:.:) s t b)
forall a b c d. (a -> b) -> (c -> d) -> p b c -> p a d
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap (:.:) s t a -> s (t a)
forall k2 k1 (f :: k2 -> *) (g :: k1 -> k2) (p :: k1).
(:.:) f g p -> f (g p)
unComp1 s (t b) -> (:.:) s t b
forall k2 k1 (f :: k2 -> *) (g :: k1 -> k2) (p :: k1).
f (g p) -> (:.:) f g p
Comp1
      (p (s (t a)) (s (t b)) -> p ((:.:) s t a) ((:.:) s t b))
-> (p a b -> p (s (t a)) (s (t b)))
-> p a b
-> p ((:.:) s t a) ((:.:) s t b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. p (t a) (t b) -> p (s (t a)) (s (t b))
forall (t :: * -> *) (p :: * -> * -> *) a b.
(Homogeneous t, Distributor p) =>
p a b -> p (t a) (t b)
forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (s a) (s b)
homogeneously (p (t a) (t b) -> p (s (t a)) (s (t b)))
-> (p a b -> p (t a) (t b)) -> p a b -> p (s (t a)) (s (t b))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. p a b -> p (t a) (t b)
forall (t :: * -> *) (p :: * -> * -> *) a b.
(Homogeneous t, Distributor p) =>
p a b -> p (t a) (t b)
forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (t a) (t b)
homogeneously
instance (Homogeneous s, Homogeneous t)
  => Homogeneous (Compose s t) where
    homogeneously :: forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (Compose s t a) (Compose s t b)
homogeneously
      = (Compose s t a -> s (t a))
-> (s (t b) -> Compose s t b)
-> p (s (t a)) (s (t b))
-> p (Compose s t a) (Compose s t b)
forall a b c d. (a -> b) -> (c -> d) -> p b c -> p a d
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap Compose s t a -> s (t a)
forall {k1} {k2} (f :: k1 -> *) (g :: k2 -> k1) (a :: k2).
Compose f g a -> f (g a)
getCompose s (t b) -> Compose s t b
forall {k} {k1} (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose
      (p (s (t a)) (s (t b)) -> p (Compose s t a) (Compose s t b))
-> (p a b -> p (s (t a)) (s (t b)))
-> p a b
-> p (Compose s t a) (Compose s t b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. p (t a) (t b) -> p (s (t a)) (s (t b))
forall (t :: * -> *) (p :: * -> * -> *) a b.
(Homogeneous t, Distributor p) =>
p a b -> p (t a) (t b)
forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (s a) (s b)
homogeneously (p (t a) (t b) -> p (s (t a)) (s (t b)))
-> (p a b -> p (t a) (t b)) -> p a b -> p (s (t a)) (s (t b))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. p a b -> p (t a) (t b)
forall (t :: * -> *) (p :: * -> * -> *) a b.
(Homogeneous t, Distributor p) =>
p a b -> p (t a) (t b)
forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (t a) (t b)
homogeneously
instance (Homogeneous s, Homogeneous t)
  => Homogeneous (s :*: t) where
    homogeneously :: forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p ((:*:) s t a) ((:*:) s t b)
homogeneously p a b
p = ((:*:) s t a -> s a)
-> ((:*:) s t a -> t a)
-> (s b -> t b -> (:*:) s t b)
-> p (s a) (s b)
-> p (t a) (t b)
-> p ((:*:) s t a) ((:*:) s t b)
forall (p :: * -> * -> *) s a c b d t.
Monoidal p =>
(s -> a) -> (s -> c) -> (b -> d -> t) -> p a b -> p c d -> p s t
dimap2
      (\(s a
s :*: t a
_) -> s a
s)
      (\(s a
_ :*: t a
t) -> t a
t)
      s b -> t b -> (:*:) s t b
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
(:*:)
      (p a b -> p (s a) (s b)
forall (t :: * -> *) (p :: * -> * -> *) a b.
(Homogeneous t, Distributor p) =>
p a b -> p (t a) (t b)
forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (s a) (s b)
homogeneously p a b
p)
      (p a b -> p (t a) (t b)
forall (t :: * -> *) (p :: * -> * -> *) a b.
(Homogeneous t, Distributor p) =>
p a b -> p (t a) (t b)
forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (t a) (t b)
homogeneously p a b
p)
instance (Homogeneous s, Homogeneous t)
  => Homogeneous (Functor.Product s t) where
    homogeneously :: forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (Product s t a) (Product s t b)
homogeneously p a b
p = (Product s t a -> s a)
-> (Product s t a -> t a)
-> (s b -> t b -> Product s t b)
-> p (s a) (s b)
-> p (t a) (t b)
-> p (Product s t a) (Product s t b)
forall (p :: * -> * -> *) s a c b d t.
Monoidal p =>
(s -> a) -> (s -> c) -> (b -> d -> t) -> p a b -> p c d -> p s t
dimap2
      (\(Functor.Pair s a
s t a
_) -> s a
s)
      (\(Functor.Pair s a
_ t a
t) -> t a
t)
      s b -> t b -> Product s t b
forall {k} (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product f g a
Functor.Pair
      (p a b -> p (s a) (s b)
forall (t :: * -> *) (p :: * -> * -> *) a b.
(Homogeneous t, Distributor p) =>
p a b -> p (t a) (t b)
forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (s a) (s b)
homogeneously p a b
p)
      (p a b -> p (t a) (t b)
forall (t :: * -> *) (p :: * -> * -> *) a b.
(Homogeneous t, Distributor p) =>
p a b -> p (t a) (t b)
forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (t a) (t b)
homogeneously p a b
p)
instance Homogeneous V1 where
  homogeneously :: forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (V1 a) (V1 b)
homogeneously p a b
_ = (V1 a -> Void) -> (Void -> V1 b) -> p Void Void -> p (V1 a) (V1 b)
forall a b c d. (a -> b) -> (c -> d) -> p b c -> p a d
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap (V1 a -> Void
\case) (Void -> V1 b
\case) p Void Void
forall (p :: * -> * -> *). Distributor p => p Void Void
zeroP
instance Homogeneous (K1 i Void) where
  homogeneously :: forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (K1 i Void a) (K1 i Void b)
homogeneously p a b
_ = (K1 i Void a -> Void)
-> (Void -> K1 i Void b)
-> p Void Void
-> p (K1 i Void a) (K1 i Void b)
forall a b c d. (a -> b) -> (c -> d) -> p b c -> p a d
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap K1 i Void a -> Void
forall k i c (p :: k). K1 i c p -> c
unK1 Void -> K1 i Void b
forall k i c (p :: k). c -> K1 i c p
K1 p Void Void
forall (p :: * -> * -> *). Distributor p => p Void Void
zeroP
instance Homogeneous (Const Void) where
  homogeneously :: forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (Const Void a) (Const Void b)
homogeneously p a b
_ = (Const Void a -> Void)
-> (Void -> Const Void b)
-> p Void Void
-> p (Const Void a) (Const Void b)
forall a b c d. (a -> b) -> (c -> d) -> p b c -> p a d
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap Const Void a -> Void
forall {k} a (b :: k). Const a b -> a
getConst Void -> Const Void b
forall {k} a (b :: k). a -> Const a b
Const p Void Void
forall (p :: * -> * -> *). Distributor p => p Void Void
zeroP
instance (Homogeneous s, Homogeneous t)
  => Homogeneous (s :+: t) where
    homogeneously :: forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p ((:+:) s t a) ((:+:) s t b)
homogeneously p a b
p = ((:+:) s t a -> Either (s a) (t a))
-> (s b -> (:+:) s t b)
-> (t b -> (:+:) s t b)
-> p (s a) (s b)
-> p (t a) (t b)
-> p ((:+:) s t a) ((:+:) s t b)
forall (p :: * -> * -> *) s a c b t d.
Distributor p =>
(s -> Either a c)
-> (b -> t) -> (d -> t) -> p a b -> p c d -> p s t
dialt
      (\case {L1 s a
s -> s a -> Either (s a) (t a)
forall a b. a -> Either a b
Left s a
s; R1 t a
t -> t a -> Either (s a) (t a)
forall a b. b -> Either a b
Right t a
t})
      s b -> (:+:) s t b
forall k (f :: k -> *) (g :: k -> *) (p :: k). f p -> (:+:) f g p
L1
      t b -> (:+:) s t b
forall k (f :: k -> *) (g :: k -> *) (p :: k). g p -> (:+:) f g p
R1
      (p a b -> p (s a) (s b)
forall (t :: * -> *) (p :: * -> * -> *) a b.
(Homogeneous t, Distributor p) =>
p a b -> p (t a) (t b)
forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (s a) (s b)
homogeneously p a b
p)
      (p a b -> p (t a) (t b)
forall (t :: * -> *) (p :: * -> * -> *) a b.
(Homogeneous t, Distributor p) =>
p a b -> p (t a) (t b)
forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (t a) (t b)
homogeneously p a b
p)
instance (Homogeneous s, Homogeneous t)
  => Homogeneous (Functor.Sum s t) where
    homogeneously :: forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (Sum s t a) (Sum s t b)
homogeneously p a b
p = (Sum s t a -> Either (s a) (t a))
-> (s b -> Sum s t b)
-> (t b -> Sum s t b)
-> p (s a) (s b)
-> p (t a) (t b)
-> p (Sum s t a) (Sum s t b)
forall (p :: * -> * -> *) s a c b t d.
Distributor p =>
(s -> Either a c)
-> (b -> t) -> (d -> t) -> p a b -> p c d -> p s t
dialt
      (\case {Functor.InL s a
s -> s a -> Either (s a) (t a)
forall a b. a -> Either a b
Left s a
s; Functor.InR t a
t -> t a -> Either (s a) (t a)
forall a b. b -> Either a b
Right t a
t})
      s b -> Sum s t b
forall {k} (f :: k -> *) (g :: k -> *) (a :: k). f a -> Sum f g a
Functor.InL
      t b -> Sum s t b
forall {k} (f :: k -> *) (g :: k -> *) (a :: k). g a -> Sum f g a
Functor.InR
      (p a b -> p (s a) (s b)
forall (t :: * -> *) (p :: * -> * -> *) a b.
(Homogeneous t, Distributor p) =>
p a b -> p (t a) (t b)
forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (s a) (s b)
homogeneously p a b
p)
      (p a b -> p (t a) (t b)
forall (t :: * -> *) (p :: * -> * -> *) a b.
(Homogeneous t, Distributor p) =>
p a b -> p (t a) (t b)
forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (t a) (t b)
homogeneously p a b
p)
instance Homogeneous t
  => Homogeneous (M1 i c t) where
    homogeneously :: forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (M1 i c t a) (M1 i c t b)
homogeneously = (M1 i c t a -> t a)
-> (t b -> M1 i c t b)
-> p (t a) (t b)
-> p (M1 i c t a) (M1 i c t b)
forall a b c d. (a -> b) -> (c -> d) -> p b c -> p a d
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap M1 i c t a -> t a
forall k i (c :: Meta) (f :: k -> *) (p :: k). M1 i c f p -> f p
unM1 t b -> M1 i c t b
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (p (t a) (t b) -> p (M1 i c t a) (M1 i c t b))
-> (p a b -> p (t a) (t b)) -> p a b -> p (M1 i c t a) (M1 i c t b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. p a b -> p (t a) (t b)
forall (t :: * -> *) (p :: * -> * -> *) a b.
(Homogeneous t, Distributor p) =>
p a b -> p (t a) (t b)
forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (t a) (t b)
homogeneously
instance Homogeneous f => Homogeneous (Rec1 f) where
  homogeneously :: forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (Rec1 f a) (Rec1 f b)
homogeneously = (Rec1 f a -> f a)
-> (f b -> Rec1 f b) -> p (f a) (f b) -> p (Rec1 f a) (Rec1 f b)
forall a b c d. (a -> b) -> (c -> d) -> p b c -> p a d
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap Rec1 f a -> f a
forall k (f :: k -> *) (p :: k). Rec1 f p -> f p
unRec1 f b -> Rec1 f b
forall k (f :: k -> *) (p :: k). f p -> Rec1 f p
Rec1 (p (f a) (f b) -> p (Rec1 f a) (Rec1 f b))
-> (p a b -> p (f a) (f b)) -> p a b -> p (Rec1 f a) (Rec1 f b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. p a b -> p (f a) (f b)
forall (t :: * -> *) (p :: * -> * -> *) a b.
(Homogeneous t, Distributor p) =>
p a b -> p (t a) (t b)
forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (f a) (f b)
homogeneously
instance Homogeneous Maybe where
  homogeneously :: forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (Maybe a) (Maybe b)
homogeneously = p a b -> p (Maybe a) (Maybe b)
forall a b. p a b -> p (Maybe a) (Maybe b)
forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (Maybe a) (Maybe b)
optionalP
instance Homogeneous [] where
  homogeneously :: forall (p :: * -> * -> *) a b. Distributor p => p a b -> p [a] [b]
homogeneously = p a b -> p [a] [b]
forall a b. p a b -> p [a] [b]
forall (p :: * -> * -> *) a b. Distributor p => p a b -> p [a] [b]
manyP
instance Homogeneous Vector where
  homogeneously :: forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (Vector a) (Vector b)
homogeneously p a b
p = Exchange
  (Either (a, Vector a) ())
  (Either (b, Vector b) ())
  (Either (a, Vector a) ())
  (Identity (Either (b, Vector b) ()))
-> Exchange
     (Either (a, Vector a) ())
     (Either (b, Vector b) ())
     (Vector a)
     (Identity (Vector b))
forall s a t b.
(Cons s s a a, AsEmpty t, Cons t t b b) =>
Iso s t (Either (a, s) ()) (Either (b, t) ())
Iso
  (Vector a)
  (Vector b)
  (Either (a, Vector a) ())
  (Either (b, Vector b) ())
eotList (Exchange
   (Either (a, Vector a) ())
   (Either (b, Vector b) ())
   (Either (a, Vector a) ())
   (Identity (Either (b, Vector b) ()))
 -> Exchange
      (Either (a, Vector a) ())
      (Either (b, Vector b) ())
      (Vector a)
      (Identity (Vector b)))
-> p (Either (a, Vector a) ()) (Either (b, Vector b) ())
-> p (Vector a) (Vector b)
forall (p :: * -> * -> *) s t a b.
Profunctor p =>
AnIso s t a b -> p a b -> p s t
>~ p a b
p p a b -> p (Vector a) (Vector b) -> p (a, Vector a) (b, Vector b)
forall (p :: * -> * -> *) a b c d.
Monoidal p =>
p a b -> p c d -> p (a, c) (b, d)
>*< p a b -> p (Vector a) (Vector b)
forall (t :: * -> *) (p :: * -> * -> *) a b.
(Homogeneous t, Distributor p) =>
p a b -> p (t a) (t b)
forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (Vector a) (Vector b)
homogeneously p a b
p p (a, Vector a) (b, Vector b)
-> p () () -> p (Either (a, Vector a) ()) (Either (b, Vector b) ())
forall a b c d. p a b -> p c d -> p (Either a c) (Either b d)
forall (p :: * -> * -> *) a b c d.
Distributor p =>
p a b -> p c d -> p (Either a c) (Either b d)
>+< p () ()
forall (p :: * -> * -> *). Monoidal p => p () ()
oneP
instance Homogeneous Seq where
  homogeneously :: forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (Seq a) (Seq b)
homogeneously p a b
p = Exchange
  (Either (a, Seq a) ())
  (Either (b, Seq b) ())
  (Either (a, Seq a) ())
  (Identity (Either (b, Seq b) ()))
-> Exchange
     (Either (a, Seq a) ())
     (Either (b, Seq b) ())
     (Seq a)
     (Identity (Seq b))
forall s a t b.
(Cons s s a a, AsEmpty t, Cons t t b b) =>
Iso s t (Either (a, s) ()) (Either (b, t) ())
Iso (Seq a) (Seq b) (Either (a, Seq a) ()) (Either (b, Seq b) ())
eotList (Exchange
   (Either (a, Seq a) ())
   (Either (b, Seq b) ())
   (Either (a, Seq a) ())
   (Identity (Either (b, Seq b) ()))
 -> Exchange
      (Either (a, Seq a) ())
      (Either (b, Seq b) ())
      (Seq a)
      (Identity (Seq b)))
-> p (Either (a, Seq a) ()) (Either (b, Seq b) ())
-> p (Seq a) (Seq b)
forall (p :: * -> * -> *) s t a b.
Profunctor p =>
AnIso s t a b -> p a b -> p s t
>~ p a b
p p a b -> p (Seq a) (Seq b) -> p (a, Seq a) (b, Seq b)
forall (p :: * -> * -> *) a b c d.
Monoidal p =>
p a b -> p c d -> p (a, c) (b, d)
>*< p a b -> p (Seq a) (Seq b)
forall (t :: * -> *) (p :: * -> * -> *) a b.
(Homogeneous t, Distributor p) =>
p a b -> p (t a) (t b)
forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (Seq a) (Seq b)
homogeneously p a b
p p (a, Seq a) (b, Seq b)
-> p () () -> p (Either (a, Seq a) ()) (Either (b, Seq b) ())
forall a b c d. p a b -> p c d -> p (Either a c) (Either b d)
forall (p :: * -> * -> *) a b c d.
Distributor p =>
p a b -> p c d -> p (Either a c) (Either b d)
>+< p () ()
forall (p :: * -> * -> *). Monoidal p => p () ()
oneP
instance Homogeneous Complex where
  homogeneously :: forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (Complex a) (Complex b)
homogeneously p a b
p = (Complex a -> a)
-> (Complex a -> a)
-> (b -> b -> Complex b)
-> p a b
-> p a b
-> p (Complex a) (Complex b)
forall (p :: * -> * -> *) s a c b d t.
Monoidal p =>
(s -> a) -> (s -> c) -> (b -> d -> t) -> p a b -> p c d -> p s t
dimap2 Complex a -> a
forall a. Complex a -> a
realPart Complex a -> a
forall a. Complex a -> a
imagPart b -> b -> Complex b
forall a. a -> a -> Complex a
(:+) p a b
p p a b
p
instance Homogeneous Tree where
  homogeneously :: forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (Tree a) (Tree b)
homogeneously p a b
p = (Tree a -> a)
-> (Tree a -> [Tree a])
-> (b -> [Tree b] -> Tree b)
-> p a b
-> p [Tree a] [Tree b]
-> p (Tree a) (Tree b)
forall (p :: * -> * -> *) s a c b d t.
Monoidal p =>
(s -> a) -> (s -> c) -> (b -> d -> t) -> p a b -> p c d -> p s t
dimap2 Tree a -> a
forall a. Tree a -> a
rootLabel Tree a -> [Tree a]
forall a. Tree a -> [Tree a]
subForest b -> [Tree b] -> Tree b
forall a. a -> [Tree a] -> Tree a
Node p a b
p (p (Tree a) (Tree b) -> p [Tree a] [Tree b]
forall a b. p a b -> p [a] [b]
forall (p :: * -> * -> *) a b. Distributor p => p a b -> p [a] [b]
manyP (p a b -> p (Tree a) (Tree b)
forall (t :: * -> *) (p :: * -> * -> *) a b.
(Homogeneous t, Distributor p) =>
p a b -> p (t a) (t b)
forall (p :: * -> * -> *) a b.
Distributor p =>
p a b -> p (Tree a) (Tree b)
homogeneously p a b
p))