module Data.Functor.Contravariant.Night (
Night(..)
, night
, runNight, necide
, assoc, unassoc
, swapped
, trans1, trans2
, intro1, intro2
, elim1, elim2
, Not(..), refuted
) where
import Control.Natural
import Data.Bifunctor
import Data.Functor.Contravariant
import Data.Functor.Contravariant.Decide
import Data.Functor.Invariant
import Data.Kind
import Data.Void
import qualified Data.Bifunctor.Assoc as B
import qualified Data.Bifunctor.Swap as B
data Night :: (Type -> Type) -> (Type -> Type) -> (Type -> Type) where
Night :: f b
-> g c
-> (a -> Either b c)
-> Night f g a
instance Contravariant (Night f g) where
contramap :: forall a' a. (a' -> a) -> Night f g a -> Night f g a'
contramap a' -> a
f (Night f b
x g c
y a -> Either b c
g) = forall (f :: * -> *) b (g :: * -> *) c a.
f b -> g c -> (a -> Either b c) -> Night f g a
Night f b
x g c
y (a -> Either b c
g forall b c a. (b -> c) -> (a -> b) -> a -> c
. a' -> a
f)
instance Invariant (Night f g) where
invmap :: forall a b. (a -> b) -> (b -> a) -> Night f g a -> Night f g b
invmap a -> b
_ b -> a
f (Night f b
x g c
y a -> Either b c
g) = forall (f :: * -> *) b (g :: * -> *) c a.
f b -> g c -> (a -> Either b c) -> Night f g a
Night f b
x g c
y (a -> Either b c
g forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> a
f)
night
:: f a
-> g b
-> Night f g (Either a b)
night :: forall (f :: * -> *) a (g :: * -> *) b.
f a -> g b -> Night f g (Either a b)
night f a
x g b
y = forall (f :: * -> *) b (g :: * -> *) c a.
f b -> g c -> (a -> Either b c) -> Night f g a
Night f a
x g b
y forall a. a -> a
id
runNight
:: Decide h
=> (f ~> h)
-> (g ~> h)
-> Night f g ~> h
runNight :: forall (h :: * -> *) (f :: * -> *) (g :: * -> *).
Decide h =>
(f ~> h) -> (g ~> h) -> Night f g ~> h
runNight f ~> h
f g ~> h
g (Night f b
x g c
y x -> Either b c
z) = forall (f :: * -> *) a b c.
Decide f =>
(a -> Either b c) -> f b -> f c -> f a
decide x -> Either b c
z (f ~> h
f f b
x) (g ~> h
g g c
y)
necide
:: Decide f
=> Night f f ~> f
necide :: forall (f :: * -> *). Decide f => Night f f ~> f
necide (Night f b
x f c
y x -> Either b c
z) = forall (f :: * -> *) a b c.
Decide f =>
(a -> Either b c) -> f b -> f c -> f a
decide x -> Either b c
z f b
x f c
y
assoc :: Night f (Night g h) ~> Night (Night f g) h
assoc :: forall (f :: * -> *) (g :: * -> *) (h :: * -> *).
Night f (Night g h) ~> Night (Night f g) h
assoc (Night f b
x (Night g b
y h c
z c -> Either b c
f) x -> Either b c
g) = forall (f :: * -> *) b (g :: * -> *) c a.
f b -> g c -> (a -> Either b c) -> Night f g a
Night (forall (f :: * -> *) b (g :: * -> *) c a.
f b -> g c -> (a -> Either b c) -> Night f g a
Night f b
x g b
y forall a. a -> a
id) h c
z (forall (p :: * -> * -> *) a b c.
Assoc p =>
p a (p b c) -> p (p a b) c
B.unassoc forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second c -> Either b c
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. x -> Either b c
g)
unassoc :: Night (Night f g) h ~> Night f (Night g h)
unassoc :: forall (f :: * -> *) (g :: * -> *) (h :: * -> *).
Night (Night f g) h ~> Night f (Night g h)
unassoc (Night (Night f b
x g c
y b -> Either b c
f) h c
z x -> Either b c
g) = forall (f :: * -> *) b (g :: * -> *) c a.
f b -> g c -> (a -> Either b c) -> Night f g a
Night f b
x (forall (f :: * -> *) b (g :: * -> *) c a.
f b -> g c -> (a -> Either b c) -> Night f g a
Night g c
y h c
z forall a. a -> a
id) (forall (p :: * -> * -> *) a b c.
Assoc p =>
p (p a b) c -> p a (p b c)
B.assoc forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first b -> Either b c
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. x -> Either b c
g)
swapped :: Night f g ~> Night g f
swapped :: forall (f :: * -> *) (g :: * -> *). Night f g ~> Night g f
swapped (Night f b
x g c
y x -> Either b c
f) = forall (f :: * -> *) b (g :: * -> *) c a.
f b -> g c -> (a -> Either b c) -> Night f g a
Night g c
y f b
x (forall (p :: * -> * -> *) a b. Swap p => p a b -> p b a
B.swap forall b c a. (b -> c) -> (a -> b) -> a -> c
. x -> Either b c
f)
trans1 :: f ~> h -> Night f g ~> Night h g
trans1 :: forall (f :: * -> *) (h :: * -> *) (g :: * -> *).
(f ~> h) -> Night f g ~> Night h g
trans1 f ~> h
f (Night f b
x g c
y x -> Either b c
z) = forall (f :: * -> *) b (g :: * -> *) c a.
f b -> g c -> (a -> Either b c) -> Night f g a
Night (f ~> h
f f b
x) g c
y x -> Either b c
z
trans2 :: g ~> h -> Night f g ~> Night f h
trans2 :: forall (g :: * -> *) (h :: * -> *) (f :: * -> *).
(g ~> h) -> Night f g ~> Night f h
trans2 g ~> h
f (Night f b
x g c
y x -> Either b c
z) = forall (f :: * -> *) b (g :: * -> *) c a.
f b -> g c -> (a -> Either b c) -> Night f g a
Night f b
x (g ~> h
f g c
y) x -> Either b c
z
newtype Not a = Not { forall a. Not a -> a -> Void
refute :: a -> Void }
refuted :: Not Void
refuted :: Not Void
refuted = forall a. (a -> Void) -> Not a
Not forall a. a -> a
id
instance Contravariant Not where
contramap :: forall a' a. (a' -> a) -> Not a -> Not a'
contramap a' -> a
f (Not a -> Void
g) = forall a. (a -> Void) -> Not a
Not (a -> Void
g forall b c a. (b -> c) -> (a -> b) -> a -> c
. a' -> a
f)
instance Invariant Not where
invmap :: forall a b. (a -> b) -> (b -> a) -> Not a -> Not b
invmap a -> b
_ = forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap
instance Semigroup (Not a) where
Not a -> Void
f <> :: Not a -> Not a -> Not a
<> Not a -> Void
g = forall a. (a -> Void) -> Not a
Not (a -> Void
f forall a. Semigroup a => a -> a -> a
<> a -> Void
g)
intro1 :: g ~> Night Not g
intro1 :: forall (g :: * -> *). g ~> Night Not g
intro1 g x
x = forall (f :: * -> *) b (g :: * -> *) c a.
f b -> g c -> (a -> Either b c) -> Night f g a
Night Not Void
refuted g x
x forall a b. b -> Either a b
Right
intro2 :: f ~> Night f Not
intro2 :: forall (f :: * -> *). f ~> Night f Not
intro2 f x
x = forall (f :: * -> *) b (g :: * -> *) c a.
f b -> g c -> (a -> Either b c) -> Night f g a
Night f x
x Not Void
refuted forall a b. a -> Either a b
Left
elim1 :: Contravariant g => Night Not g ~> g
elim1 :: forall (g :: * -> *). Contravariant g => Night Not g ~> g
elim1 (Night Not b
x g c
y x -> Either b c
z) = forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a. Void -> a
absurd forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Not a -> a -> Void
refute Not b
x) forall a. a -> a
id forall b c a. (b -> c) -> (a -> b) -> a -> c
. x -> Either b c
z) g c
y
elim2 :: Contravariant f => Night f Not ~> f
elim2 :: forall (f :: * -> *). Contravariant f => Night f Not ~> f
elim2 (Night f b
x Not c
y x -> Either b c
z) = forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a. a -> a
id (forall a. Void -> a
absurd forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Not a -> a -> Void
refute Not c
y) forall b c a. (b -> c) -> (a -> b) -> a -> c
. x -> Either b c
z) f b
x