-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Leibnizian equality
--   
--   Leibnizian equality.
@package eq
@version 4.2


-- | Leibnizian equality. Injectivity in the presence of type families is
--   provided by a generalization of a trick by Oleg Kiselyov posted here:
--   
--   
--   <a>http://www.haskell.org/pipermail/haskell-cafe/2010-May/077177.html</a>
module Data.Eq.Type

-- | Leibnizian equality states that two things are equal if you can
--   substitute one for the other in all contexts
newtype a (:=) b
Refl :: forall c. c a -> c b -> (:=) a b
[subst] :: (:=) a b -> forall c. c a -> c b

-- | Equality is reflexive
refl :: a := a

-- | Equality is transitive
trans :: a := b -> b := c -> a := c

-- | Equality is symmetric
symm :: (a := b) -> (b := a)

-- | If two things are equal you can convert one to the other
coerce :: a := b -> a -> b

-- | You can lift equality into any type constructor
lift :: a := b -> f a := f b

-- | ... in any position
lift2 :: a := b -> f a c := f b c
lift2' :: a := b -> c := d -> f a c := f b d
lift3 :: a := b -> f a c d := f b c d
lift3' :: a := b -> c := d -> e := f -> g a c e := g b d f

-- | Type constructors are injective, so you can lower equality through any
--   type constructor ...
lower :: forall a b f. f a := f b -> a := b

-- | ... in any position ...
lower2 :: forall a b c f. f a c := f b c -> a := b

-- | ... these definitions are poly-kinded on GHC 7.6 and up.
lower3 :: forall a b c d f. f a c d := f b c d -> a := b
fromLeibniz :: a := b -> a :~: b
toLeibniz :: a :~: b -> a := b
reprLeibniz :: a := b -> Coercion a b
instance Control.Category.Category (Data.Eq.Type.:=)
instance Data.Semigroupoid.Semigroupoid (Data.Eq.Type.:=)
instance Data.Groupoid.Groupoid (Data.Eq.Type.:=)
instance forall k (a :: k). Data.Type.Equality.TestEquality ((Data.Eq.Type.:=) a)
instance forall k (a :: k). Data.Type.Coercion.TestCoercion ((Data.Eq.Type.:=) a)


-- | Leibnizian equality à la <a>Data.Eq.Type</a>, generalized to be
--   heterogenous using higher-rank kinds.
--   
--   This module is only exposed on GHC 8.2 and later.
module Data.Eq.Type.Hetero

-- | Heterogeneous Leibnizian equality.
--   
--   Leibnizian equality states that two things are equal if you can
--   substitute one for the other in all contexts.
newtype (a :: j) (:==) (b :: k)
HRefl :: forall (c :: forall (i :: Type). i -> Type). c a -> c b -> (:==)
[hsubst] :: (:==) -> forall (c :: forall (i :: Type). i -> Type). c a -> c b

-- | Equality is reflexive.
refl :: a :== a

-- | Equality is transitive.
trans :: a :== b -> b :== c -> a :== c

-- | Equality is symmetric.
symm :: a :== b -> b :== a

-- | If two things are equal, you can convert one to the other.
coerce :: a :== b -> a -> b

-- | You can lift equality into any type constructor...
lift :: a :== b -> f a :== f b

-- | ... in any position.
lift2 :: a :== b -> f a c :== f b c
lift2' :: a :== b -> c :== d -> f a c :== f b d
lift3 :: a :== b -> f a c d :== f b c d
lift3' :: a :== b -> c :== d -> e :== f -> g a c e :== g b d f

-- | Type constructors are injective, so you can lower equality through any
--   type constructor.
lower :: forall (j :: Type) (k :: Type) (f :: j -> k) (a :: j) (b :: j). f a :== f b -> a :== b
lower2 :: forall (i :: Type) (j :: Type) (k :: Type) (f :: i -> j -> k) (a :: i) (b :: i) (c :: j). f a c :== f b c -> a :== b
lower3 :: forall (h :: Type) (i :: Type) (j :: Type) (k :: Type) (f :: h -> i -> j -> k) (a :: h) (b :: h) (c :: i) (d :: j). f a c d :== f b c d -> a :== b

-- | Convert an appropriately kinded heterogeneous Leibnizian equality into
--   a homogeneous Leibnizian equality '(ET.:=)'.
toHomogeneous :: a :== b -> a := b

-- | Convert a homogeneous Leibnizian equality '(ET.:=)' to an
--   appropriately kinded heterogeneous Leibizian equality.
fromHomogeneous :: a := b -> a :== b
fromLeibniz :: forall a b. a :== b -> a :~: b
toLeibniz :: a :~: b -> a :== b
heteroFromLeibniz :: a :== b -> a :~~: b
heteroToLeibniz :: a :~~: b -> a :== b
reprLeibniz :: a :== b -> Coercion a b
instance Control.Category.Category (Data.Eq.Type.Hetero.:==)
instance Data.Semigroupoid.Semigroupoid (Data.Eq.Type.Hetero.:==)
instance Data.Groupoid.Groupoid (Data.Eq.Type.Hetero.:==)
instance forall k j (a :: j). Data.Type.Equality.TestEquality ((Data.Eq.Type.Hetero.:==) a)
instance forall k j (a :: j). Data.Type.Coercion.TestCoercion ((Data.Eq.Type.Hetero.:==) a)
