module Data.Functor.Invariant.Night (
Night(..)
, Not(..), refuted
, night
, runNightAlt
, runNightDecide
, toCoNight
, toCoNight_
, toContraNight
, assoc, unassoc
, intro1, intro2
, elim1, elim2
, swapped
, trans1, trans2
) where
import Control.Natural
import Data.Bifunctor
import Data.Functor.Alt
import Data.Functor.Contravariant.Decide
import Data.Functor.Contravariant.Night (Not(..), refuted)
import Data.Functor.Invariant
import Data.Kind
import Data.Void
import GHC.Generics
import qualified Data.Bifunctor.Assoc as B
import qualified Data.Bifunctor.Swap as B
import qualified Data.Functor.Contravariant.Night as CN
import qualified Data.Functor.Coyoneda as CY
data Night :: (Type -> Type) -> (Type -> Type) -> (Type -> Type) where
Night :: f b
-> g c
-> (a -> Either b c)
-> (b -> a)
-> (c -> a)
-> Night f g a
instance Invariant (Night f g) where
invmap :: (a -> b) -> (b -> a) -> Night f g a -> Night f g b
invmap f :: a -> b
f g :: b -> a
g (Night x :: f b
x y :: g c
y h :: a -> Either b c
h j :: b -> a
j k :: c -> a
k) = f b
-> g c -> (b -> Either b c) -> (b -> b) -> (c -> b) -> Night f g b
forall (f :: * -> *) b (g :: * -> *) c a.
f b
-> g c -> (a -> Either b c) -> (b -> a) -> (c -> a) -> Night f g a
Night f b
x g c
y (a -> Either b c
h (a -> Either b c) -> (b -> a) -> b -> Either b c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> a
g) (a -> b
f (a -> b) -> (b -> a) -> b -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> a
j) (a -> b
f (a -> b) -> (c -> a) -> c -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. c -> a
k)
night :: f a -> g b -> Night f g (Either a b)
night :: f a -> g b -> Night f g (Either a b)
night x :: f a
x y :: g b
y = f a
-> g b
-> (Either a b -> Either a b)
-> (a -> Either a b)
-> (b -> Either a b)
-> Night f g (Either a b)
forall (f :: * -> *) b (g :: * -> *) c a.
f b
-> g c -> (a -> Either b c) -> (b -> a) -> (c -> a) -> Night f g a
Night f a
x g b
y Either a b -> Either a b
forall a. a -> a
id a -> Either a b
forall a b. a -> Either a b
Left b -> Either a b
forall a b. b -> Either a b
Right
runNightAlt
:: forall f g h. Alt h
=> f ~> h
-> g ~> h
-> Night f g ~> h
runNightAlt :: (f ~> h) -> (g ~> h) -> Night f g ~> h
runNightAlt f :: f ~> h
f g :: g ~> h
g (Night x :: f b
x y :: g c
y _ j :: b -> x
j k :: c -> x
k) = (b -> x) -> h b -> h x
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap b -> x
j (f b -> h b
f ~> h
f f b
x) h x -> h x -> h x
forall (f :: * -> *) a. Alt f => f a -> f a -> f a
<!> (c -> x) -> h c -> h x
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap c -> x
k (g c -> h c
g ~> h
g g c
y)
runNightDecide
:: forall f g h. Decide h
=> f ~> h
-> g ~> h
-> Night f g ~> h
runNightDecide :: (f ~> h) -> (g ~> h) -> Night f g ~> h
runNightDecide f :: f ~> h
f g :: g ~> h
g (Night x :: f b
x y :: g c
y h :: x -> Either b c
h _ _) = (x -> Either b c) -> h b -> h c -> h x
forall (f :: * -> *) a b c.
Decide f =>
(a -> Either b c) -> f b -> f c -> f a
decide x -> Either b c
h (f b -> h b
f ~> h
f f b
x) (g c -> h c
g ~> h
g g c
y)
toCoNight :: (Functor f, Functor g) => Night f g ~> f :*: g
toCoNight :: Night f g ~> (f :*: g)
toCoNight (Night x :: f b
x y :: g c
y _ f :: b -> x
f g :: c -> x
g) = (b -> x) -> f b -> f x
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap b -> x
f f b
x f x -> g x -> (:*:) f g x
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: (c -> x) -> g c -> g x
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap c -> x
g g c
y
toCoNight_ :: Night f g ~> CY.Coyoneda f :*: CY.Coyoneda g
toCoNight_ :: Night f g x -> (:*:) (Coyoneda f) (Coyoneda g) x
toCoNight_ (Night x :: f b
x y :: g c
y _ f :: b -> x
f g :: c -> x
g) = (b -> x) -> f b -> Coyoneda f x
forall b a (f :: * -> *). (b -> a) -> f b -> Coyoneda f a
CY.Coyoneda b -> x
f f b
x Coyoneda f x -> Coyoneda g x -> (:*:) (Coyoneda f) (Coyoneda g) x
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: (c -> x) -> g c -> Coyoneda g x
forall b a (f :: * -> *). (b -> a) -> f b -> Coyoneda f a
CY.Coyoneda c -> x
g g c
y
toContraNight :: Night f g ~> CN.Night f g
toContraNight :: Night f g x -> Night f g x
toContraNight (Night x :: f b
x y :: g c
y f :: x -> Either b c
f _ _) = f b -> g c -> (x -> Either b c) -> Night f g x
forall (f :: * -> *) b (g :: * -> *) c a.
f b -> g c -> (a -> Either b c) -> Night f g a
CN.Night f b
x g c
y x -> Either b c
f
assoc :: Night f (Night g h) ~> Night (Night f g) h
assoc :: Night f (Night g h) x -> Night (Night f g) h x
assoc (Night x :: f b
x (Night y :: g b
y z :: h c
z f :: c -> Either b c
f g :: b -> c
g h :: c -> c
h) j :: x -> Either b c
j k :: b -> x
k l :: c -> x
l) =
Night f g (Either b b)
-> h c
-> (x -> Either (Either b b) c)
-> (Either b b -> x)
-> (c -> x)
-> Night (Night f g) h x
forall (f :: * -> *) b (g :: * -> *) c a.
f b
-> g c -> (a -> Either b c) -> (b -> a) -> (c -> a) -> Night f g a
Night (f b
-> g b
-> (Either b b -> Either b b)
-> (b -> Either b b)
-> (b -> Either b b)
-> Night f g (Either b b)
forall (f :: * -> *) b (g :: * -> *) c a.
f b
-> g c -> (a -> Either b c) -> (b -> a) -> (c -> a) -> Night f g a
Night f b
x g b
y Either b b -> Either b b
forall a. a -> a
id b -> Either b b
forall a b. a -> Either a b
Left b -> Either b b
forall a b. b -> Either a b
Right) h c
z
(Either b (Either b c) -> Either (Either b b) c
forall (p :: * -> * -> *) a b c.
Assoc p =>
p a (p b c) -> p (p a b) c
B.unassoc (Either b (Either b c) -> Either (Either b b) c)
-> (x -> Either b (Either b c)) -> x -> Either (Either b b) c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (c -> Either b c) -> Either b c -> Either b (Either b c)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second c -> Either b c
f (Either b c -> Either b (Either b c))
-> (x -> Either b c) -> x -> Either b (Either b c)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. x -> Either b c
j)
((b -> x) -> (b -> x) -> Either b b -> x
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either b -> x
k (c -> x
l (c -> x) -> (b -> c) -> b -> x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> c
g))
(c -> x
l (c -> x) -> (c -> c) -> c -> x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. c -> c
h)
unassoc :: Night (Night f g) h ~> Night f (Night g h)
unassoc :: Night (Night f g) h x -> Night f (Night g h) x
unassoc (Night (Night x :: f b
x y :: g c
y f :: b -> Either b c
f g :: b -> b
g h :: c -> b
h) z :: h c
z j :: x -> Either b c
j k :: b -> x
k l :: c -> x
l) =
f b
-> Night g h (Either c c)
-> (x -> Either b (Either c c))
-> (b -> x)
-> (Either c c -> x)
-> Night f (Night g h) x
forall (f :: * -> *) b (g :: * -> *) c a.
f b
-> g c -> (a -> Either b c) -> (b -> a) -> (c -> a) -> Night f g a
Night f b
x (g c
-> h c
-> (Either c c -> Either c c)
-> (c -> Either c c)
-> (c -> Either c c)
-> Night g h (Either c c)
forall (f :: * -> *) b (g :: * -> *) c a.
f b
-> g c -> (a -> Either b c) -> (b -> a) -> (c -> a) -> Night f g a
Night g c
y h c
z Either c c -> Either c c
forall a. a -> a
id c -> Either c c
forall a b. a -> Either a b
Left c -> Either c c
forall a b. b -> Either a b
Right)
(Either (Either b c) c -> Either b (Either c c)
forall (p :: * -> * -> *) a b c.
Assoc p =>
p (p a b) c -> p a (p b c)
B.assoc (Either (Either b c) c -> Either b (Either c c))
-> (x -> Either (Either b c) c) -> x -> Either b (Either c c)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (b -> Either b c) -> Either b c -> Either (Either b c) c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first b -> Either b c
f (Either b c -> Either (Either b c) c)
-> (x -> Either b c) -> x -> Either (Either b c) c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. x -> Either b c
j)
(b -> x
k (b -> x) -> (b -> b) -> b -> x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> b
g)
((c -> x) -> (c -> x) -> Either c c -> x
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (b -> x
k (b -> x) -> (c -> b) -> c -> x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. c -> b
h) c -> x
l)
intro1 :: g ~> Night Not g
intro1 :: g x -> Night Not g x
intro1 y :: g x
y = Not Void
-> g x
-> (x -> Either Void x)
-> (Void -> x)
-> (x -> x)
-> Night Not g x
forall (f :: * -> *) b (g :: * -> *) c a.
f b
-> g c -> (a -> Either b c) -> (b -> a) -> (c -> a) -> Night f g a
Night Not Void
refuted g x
y x -> Either Void x
forall a b. b -> Either a b
Right Void -> x
forall a. Void -> a
absurd x -> x
forall a. a -> a
id
intro2 :: f ~> Night f Not
intro2 :: f x -> Night f Not x
intro2 x :: f x
x = f x
-> Not Void
-> (x -> Either x Void)
-> (x -> x)
-> (Void -> x)
-> Night f Not x
forall (f :: * -> *) b (g :: * -> *) c a.
f b
-> g c -> (a -> Either b c) -> (b -> a) -> (c -> a) -> Night f g a
Night f x
x Not Void
refuted x -> Either x Void
forall a b. a -> Either a b
Left x -> x
forall a. a -> a
id Void -> x
forall a. Void -> a
absurd
elim1 :: Invariant g => Night Not g ~> g
elim1 :: Night Not g ~> g
elim1 (Night x :: Not b
x y :: g c
y f :: x -> Either b c
f _ h :: c -> x
h) = (c -> x) -> (x -> c) -> g c -> g x
forall (f :: * -> *) a b.
Invariant f =>
(a -> b) -> (b -> a) -> f a -> f b
invmap c -> x
h ((b -> c) -> (c -> c) -> Either b c -> c
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Void -> c
forall a. Void -> a
absurd (Void -> c) -> (b -> Void) -> b -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Not b -> b -> Void
forall a. Not a -> a -> Void
refute Not b
x) c -> c
forall a. a -> a
id (Either b c -> c) -> (x -> Either b c) -> x -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. x -> Either b c
f) g c
y
elim2 :: Invariant f => Night f Not ~> f
elim2 :: Night f Not ~> f
elim2 (Night x :: f b
x y :: Not c
y f :: x -> Either b c
f g :: b -> x
g _) = (b -> x) -> (x -> b) -> f b -> f x
forall (f :: * -> *) a b.
Invariant f =>
(a -> b) -> (b -> a) -> f a -> f b
invmap b -> x
g ((b -> b) -> (c -> b) -> Either b c -> b
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either b -> b
forall a. a -> a
id (Void -> b
forall a. Void -> a
absurd (Void -> b) -> (c -> Void) -> c -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Not c -> c -> Void
forall a. Not a -> a -> Void
refute Not c
y) (Either b c -> b) -> (x -> Either b c) -> x -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. x -> Either b c
f) f b
x
swapped :: Night f g ~> Night g f
swapped :: Night f g x -> Night g f x
swapped (Night x :: f b
x y :: g c
y f :: x -> Either b c
f g :: b -> x
g h :: c -> x
h) = g c
-> f b -> (x -> Either c b) -> (c -> x) -> (b -> x) -> Night g f x
forall (f :: * -> *) b (g :: * -> *) c a.
f b
-> g c -> (a -> Either b c) -> (b -> a) -> (c -> a) -> Night f g a
Night g c
y f b
x (Either b c -> Either c b
forall (p :: * -> * -> *) a b. Swap p => p a b -> p b a
B.swap (Either b c -> Either c b) -> (x -> Either b c) -> x -> Either c b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. x -> Either b c
f) c -> x
h b -> x
g
trans1 :: f ~> h -> Night f g ~> Night h g
trans1 :: (f ~> h) -> Night f g ~> Night h g
trans1 f :: f ~> h
f (Night x :: f b
x y :: g c
y g :: x -> Either b c
g h :: b -> x
h j :: c -> x
j) = h b
-> g c -> (x -> Either b c) -> (b -> x) -> (c -> x) -> Night h g x
forall (f :: * -> *) b (g :: * -> *) c a.
f b
-> g c -> (a -> Either b c) -> (b -> a) -> (c -> a) -> Night f g a
Night (f b -> h b
f ~> h
f f b
x) g c
y x -> Either b c
g b -> x
h c -> x
j
trans2 :: g ~> h -> Night f g ~> Night f h
trans2 :: (g ~> h) -> Night f g ~> Night f h
trans2 f :: g ~> h
f (Night x :: f b
x y :: g c
y g :: x -> Either b c
g h :: b -> x
h j :: c -> x
j) = f b
-> h c -> (x -> Either b c) -> (b -> x) -> (c -> x) -> Night f h x
forall (f :: * -> *) b (g :: * -> *) c a.
f b
-> g c -> (a -> Either b c) -> (b -> a) -> (c -> a) -> Night f g a
Night f b
x (g c -> h c
g ~> h
f g c
y) x -> Either b c
g b -> x
h c -> x
j