{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE KindSignatures #-}
module Data.Functor.Contravariant.Day
( Day(..)
, day
, runDay
, assoc, disassoc
, swapped
, intro1, intro2
, day1, day2
, diag
, trans1, trans2
) where
import Control.Arrow ((***))
import Data.Functor.Contravariant
import Data.Functor.Contravariant.Rep
import Data.Functor.Contravariant.Adjunction
import Data.Functor.Contravariant.Divisible
import Data.Proxy
import Data.Tuple (swap)
import Data.Typeable
data Day f g a = forall b c. Day (f b) (g c) (a -> (b, c))
deriving Typeable
day :: f a -> g b -> Day f g (a, b)
day :: forall (f :: * -> *) a (g :: * -> *) b.
f a -> g b -> Day f g (a, b)
day f a
fa g b
gb = f a -> g b -> ((a, b) -> (a, b)) -> Day f g (a, b)
forall (f :: * -> *) (g :: * -> *) a b c.
f b -> g c -> (a -> (b, c)) -> Day f g a
Day f a
fa g b
gb (a, b) -> (a, b)
forall a. a -> a
id
instance Contravariant (Day f g) where
contramap :: forall a' a. (a' -> a) -> Day f g a -> Day f g a'
contramap a' -> a
f (Day f b
fb g c
gc a -> (b, c)
abc) = f b -> g c -> (a' -> (b, c)) -> Day f g a'
forall (f :: * -> *) (g :: * -> *) a b c.
f b -> g c -> (a -> (b, c)) -> Day f g a
Day f b
fb g c
gc (a -> (b, c)
abc (a -> (b, c)) -> (a' -> a) -> a' -> (b, c)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a' -> a
f)
instance (Divisible f, Divisible g) => Divisible (Day f g) where
divide :: forall a b c. (a -> (b, c)) -> Day f g b -> Day f g c -> Day f g a
divide a -> (b, c)
h (Day f b
f g c
g b -> (b, c)
l) (Day f b
f' g c
g' c -> (b, c)
r) = f (b, b) -> g (c, c) -> (a -> ((b, b), (c, c))) -> Day f g a
forall (f :: * -> *) (g :: * -> *) a b c.
f b -> g c -> (a -> (b, c)) -> Day f g a
Day (f b -> f b -> f (b, b)
forall (f :: * -> *) a b. Divisible f => f a -> f b -> f (a, b)
divided f b
f f b
f') (g c -> g c -> g (c, c)
forall (f :: * -> *) a b. Divisible f => f a -> f b -> f (a, b)
divided g c
g g c
g') (((b, c), (b, c)) -> ((b, b), (c, c))
forall {a} {a} {b} {b}. ((a, a), (b, b)) -> ((a, b), (a, b))
intertwine (((b, c), (b, c)) -> ((b, b), (c, c)))
-> (a -> ((b, c), (b, c))) -> a -> ((b, b), (c, c))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (b -> (b, c)
l (b -> (b, c)) -> (c -> (b, c)) -> (b, c) -> ((b, c), (b, c))
forall b c b' c'. (b -> c) -> (b' -> c') -> (b, b') -> (c, c')
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** c -> (b, c)
r) ((b, c) -> ((b, c), (b, c)))
-> (a -> (b, c)) -> a -> ((b, c), (b, c))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> (b, c)
h)
where intertwine :: ((a, a), (b, b)) -> ((a, b), (a, b))
intertwine ((a
a, a
b), (b
c, b
d)) = ((a
a, b
c), (a
b, b
d))
conquer :: forall a. Day f g a
conquer = f a -> g a -> (a -> (a, a)) -> Day f g a
forall (f :: * -> *) (g :: * -> *) a b c.
f b -> g c -> (a -> (b, c)) -> Day f g a
Day f a
forall a. f a
forall (f :: * -> *) a. Divisible f => f a
conquer g a
forall a. g a
forall (f :: * -> *) a. Divisible f => f a
conquer (\a
a -> (a
a, a
a))
instance (Representable f, Representable g) => Representable (Day f g) where
type Rep (Day f g) = (Rep f, Rep g)
tabulate :: forall a. (a -> Rep (Day f g)) -> Day f g a
tabulate a -> Rep (Day f g)
a2fg = f (Rep f, Rep g)
-> g (Rep f, Rep g)
-> (a -> ((Rep f, Rep g), (Rep f, Rep g)))
-> Day f g a
forall (f :: * -> *) (g :: * -> *) a b c.
f b -> g c -> (a -> (b, c)) -> Day f g a
Day (((Rep f, Rep g) -> Rep f) -> f (Rep f, Rep g)
forall a. (a -> Rep f) -> f a
forall (f :: * -> *) a. Representable f => (a -> Rep f) -> f a
tabulate (Rep f, Rep g) -> Rep f
forall a b. (a, b) -> a
fst) (((Rep f, Rep g) -> Rep g) -> g (Rep f, Rep g)
forall a. (a -> Rep g) -> g a
forall (f :: * -> *) a. Representable f => (a -> Rep f) -> f a
tabulate (Rep f, Rep g) -> Rep g
forall a b. (a, b) -> b
snd) ((a -> ((Rep f, Rep g), (Rep f, Rep g))) -> Day f g a)
-> (a -> ((Rep f, Rep g), (Rep f, Rep g))) -> Day f g a
forall a b. (a -> b) -> a -> b
$ \a
a -> let b :: Rep (Day f g)
b = a -> Rep (Day f g)
a2fg a
a in ((Rep f, Rep g)
Rep (Day f g)
b,(Rep f, Rep g)
Rep (Day f g)
b)
index :: forall a. Day f g a -> a -> Rep (Day f g)
index (Day f b
fb g c
gc a -> (b, c)
abc) a
a = case a -> (b, c)
abc a
a of
(b
b, c
c) -> (f b -> b -> Rep f
forall a. f a -> a -> Rep f
forall (f :: * -> *) a. Representable f => f a -> a -> Rep f
index f b
fb b
b, g c -> c -> Rep g
forall a. g a -> a -> Rep g
forall (f :: * -> *) a. Representable f => f a -> a -> Rep f
index g c
gc c
c)
{-# INLINE index #-}
contramapWithRep :: forall b a.
(b -> Either a (Rep (Day f g))) -> Day f g a -> Day f g b
contramapWithRep b -> Either a (Rep (Day f g))
d2eafg (Day f b
fb g c
gc a -> (b, c)
abc) = f (Either b (Rep f))
-> g (Either c (Rep g))
-> (b -> (Either b (Rep f), Either c (Rep g)))
-> Day f g b
forall (f :: * -> *) (g :: * -> *) a b c.
f b -> g c -> (a -> (b, c)) -> Day f g a
Day ((Either b (Rep f) -> Either b (Rep f))
-> f b -> f (Either b (Rep f))
forall b a. (b -> Either a (Rep f)) -> f a -> f b
forall (f :: * -> *) b a.
Representable f =>
(b -> Either a (Rep f)) -> f a -> f b
contramapWithRep Either b (Rep f) -> Either b (Rep f)
forall a. a -> a
id f b
fb) ((Either c (Rep g) -> Either c (Rep g))
-> g c -> g (Either c (Rep g))
forall b a. (b -> Either a (Rep g)) -> g a -> g b
forall (f :: * -> *) b a.
Representable f =>
(b -> Either a (Rep f)) -> f a -> f b
contramapWithRep Either c (Rep g) -> Either c (Rep g)
forall a. a -> a
id g c
gc) ((b -> (Either b (Rep f), Either c (Rep g))) -> Day f g b)
-> (b -> (Either b (Rep f), Either c (Rep g))) -> Day f g b
forall a b. (a -> b) -> a -> b
$ \b
d -> case b -> Either a (Rep (Day f g))
d2eafg b
d of
Left a
a -> case a -> (b, c)
abc a
a of
(b
b, c
c) -> (b -> Either b (Rep f)
forall a b. a -> Either a b
Left b
b, c -> Either c (Rep g)
forall a b. a -> Either a b
Left c
c)
Right (Rep f
vf, Rep g
vg) -> (Rep f -> Either b (Rep f)
forall a b. b -> Either a b
Right Rep f
vf, Rep g -> Either c (Rep g)
forall a b. b -> Either a b
Right Rep g
vg)
{-# INLINE tabulate #-}
instance (Adjunction f u, Adjunction f' u') => Adjunction (Day f f') (Day u u') where
unit :: forall a. a -> Day u u' (Day f f' a)
unit a
a = u (f a)
-> u' (f' a)
-> (Day f f' a -> (f a, f' a))
-> Day u u' (Day f f' a)
forall (f :: * -> *) (g :: * -> *) a b c.
f b -> g c -> (a -> (b, c)) -> Day f g a
Day (a -> u (f a)
forall a. a -> u (f a)
forall (f :: * -> *) (g :: * -> *) a.
Adjunction f g =>
a -> g (f a)
unit a
a) (a -> u' (f' a)
forall a. a -> u' (f' a)
forall (f :: * -> *) (g :: * -> *) a.
Adjunction f g =>
a -> g (f a)
unit a
a) (\(Day f b
f f' c
f' a -> (b, c)
g) -> ((a -> b) -> f b -> f a
forall a' a. (a' -> a) -> f a -> f a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap ((b, c) -> b
forall a b. (a, b) -> a
fst ((b, c) -> b) -> (a -> (b, c)) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> (b, c)
g) f b
f, (a -> c) -> f' c -> f' a
forall a' a. (a' -> a) -> f' a -> f' a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap ((b, c) -> c
forall a b. (a, b) -> b
snd ((b, c) -> c) -> (a -> (b, c)) -> a -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> (b, c)
g) f' c
f'))
counit :: forall a. a -> Day f f' (Day u u' a)
counit a
a = f (u a)
-> f' (u' a)
-> (Day u u' a -> (u a, u' a))
-> Day f f' (Day u u' a)
forall (f :: * -> *) (g :: * -> *) a b c.
f b -> g c -> (a -> (b, c)) -> Day f g a
Day (a -> f (u a)
forall a. a -> f (u a)
forall (f :: * -> *) (g :: * -> *) a.
Adjunction f g =>
a -> f (g a)
counit a
a) (a -> f' (u' a)
forall a. a -> f' (u' a)
forall (f :: * -> *) (g :: * -> *) a.
Adjunction f g =>
a -> f (g a)
counit a
a) (\(Day u b
u u' c
u' a -> (b, c)
g) -> ((a -> b) -> u b -> u a
forall a' a. (a' -> a) -> u a -> u a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap ((b, c) -> b
forall a b. (a, b) -> a
fst ((b, c) -> b) -> (a -> (b, c)) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> (b, c)
g) u b
u, (a -> c) -> u' c -> u' a
forall a' a. (a' -> a) -> u' a -> u' a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap ((b, c) -> c
forall a b. (a, b) -> b
snd ((b, c) -> c) -> (a -> (b, c)) -> a -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> (b, c)
g) u' c
u'))
runDay :: (Contravariant f, Contravariant g) => Day f g a -> (f a, g a)
runDay :: forall (f :: * -> *) (g :: * -> *) a.
(Contravariant f, Contravariant g) =>
Day f g a -> (f a, g a)
runDay (Day f b
fb g c
gc a -> (b, c)
abc) =
( (a -> b) -> f b -> f a
forall a' a. (a' -> a) -> f a -> f a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap ((b, c) -> b
forall a b. (a, b) -> a
fst ((b, c) -> b) -> (a -> (b, c)) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> (b, c)
abc) f b
fb
, (a -> c) -> g c -> g a
forall a' a. (a' -> a) -> g a -> g a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap ((b, c) -> c
forall a b. (a, b) -> b
snd ((b, c) -> c) -> (a -> (b, c)) -> a -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> (b, c)
abc) g c
gc
)
assoc :: Day f (Day g h) a -> Day (Day f g) h a
assoc :: forall (f :: * -> *) (g :: * -> *) (h :: * -> *) a.
Day f (Day g h) a -> Day (Day f g) h a
assoc (Day f b
fb (Day g b
gd h c
he c -> (b, c)
cde) a -> (b, c)
abc) = Day f g (b, b) -> h c -> (a -> ((b, b), c)) -> Day (Day f g) h a
forall (f :: * -> *) (g :: * -> *) a b c.
f b -> g c -> (a -> (b, c)) -> Day f g a
Day (f b -> g b -> ((b, b) -> (b, b)) -> Day f g (b, b)
forall (f :: * -> *) (g :: * -> *) a b c.
f b -> g c -> (a -> (b, c)) -> Day f g a
Day f b
fb g b
gd (b, b) -> (b, b)
forall a. a -> a
id) h c
he ((a -> ((b, b), c)) -> Day (Day f g) h a)
-> (a -> ((b, b), c)) -> Day (Day f g) h a
forall a b. (a -> b) -> a -> b
$ \a
a ->
case c -> (b, c)
cde (c -> (b, c)) -> (b, c) -> (b, (b, c))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> (b, c)
abc a
a of
(b
b, (b
d, c
e)) -> ((b
b, b
d), c
e)
disassoc :: Day (Day f g) h a -> Day f (Day g h) a
disassoc :: forall (f :: * -> *) (g :: * -> *) (h :: * -> *) a.
Day (Day f g) h a -> Day f (Day g h) a
disassoc (Day (Day f b
fd g c
ge b -> (b, c)
bde) h c
hc a -> (b, c)
abc) = f b -> Day g h (c, c) -> (a -> (b, (c, c))) -> Day f (Day g h) a
forall (f :: * -> *) (g :: * -> *) a b c.
f b -> g c -> (a -> (b, c)) -> Day f g a
Day f b
fd (g c -> h c -> ((c, c) -> (c, c)) -> Day g h (c, c)
forall (f :: * -> *) (g :: * -> *) a b c.
f b -> g c -> (a -> (b, c)) -> Day f g a
Day g c
ge h c
hc (c, c) -> (c, c)
forall a. a -> a
id) ((a -> (b, (c, c))) -> Day f (Day g h) a)
-> (a -> (b, (c, c))) -> Day f (Day g h) a
forall a b. (a -> b) -> a -> b
$ \a
a ->
case a -> (b, c)
abc a
a of
(b
b, c
c) -> case b -> (b, c)
bde b
b of
(b
d, c
e) -> (b
d, (c
e, c
c))
swapped :: Day f g a -> Day g f a
swapped :: forall (f :: * -> *) (g :: * -> *) a. Day f g a -> Day g f a
swapped (Day f b
fb g c
gc a -> (b, c)
abc) = g c -> f b -> (a -> (c, b)) -> Day g f a
forall (f :: * -> *) (g :: * -> *) a b c.
f b -> g c -> (a -> (b, c)) -> Day f g a
Day g c
gc f b
fb ((b, c) -> (c, b)
forall a b. (a, b) -> (b, a)
swap ((b, c) -> (c, b)) -> (a -> (b, c)) -> a -> (c, b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> (b, c)
abc)
intro1 :: f a -> Day Proxy f a
intro1 :: forall (f :: * -> *) a. f a -> Day Proxy f a
intro1 f a
fa = Proxy () -> f a -> (a -> ((), a)) -> Day Proxy f a
forall (f :: * -> *) (g :: * -> *) a b c.
f b -> g c -> (a -> (b, c)) -> Day f g a
Day Proxy ()
forall {k} (t :: k). Proxy t
Proxy f a
fa ((a -> ((), a)) -> Day Proxy f a)
-> (a -> ((), a)) -> Day Proxy f a
forall a b. (a -> b) -> a -> b
$ \a
a -> ((),a
a)
intro2 :: f a -> Day f Proxy a
intro2 :: forall (f :: * -> *) a. f a -> Day f Proxy a
intro2 f a
fa = f a -> Proxy () -> (a -> (a, ())) -> Day f Proxy a
forall (f :: * -> *) (g :: * -> *) a b c.
f b -> g c -> (a -> (b, c)) -> Day f g a
Day f a
fa Proxy ()
forall {k} (t :: k). Proxy t
Proxy ((a -> (a, ())) -> Day f Proxy a)
-> (a -> (a, ())) -> Day f Proxy a
forall a b. (a -> b) -> a -> b
$ \a
a -> (a
a,())
day1 :: Contravariant f => Day f g a -> f a
day1 :: forall (f :: * -> *) (g :: * -> *) a.
Contravariant f =>
Day f g a -> f a
day1 (Day f b
fb g c
_ a -> (b, c)
abc) = (a -> b) -> f b -> f a
forall a' a. (a' -> a) -> f a -> f a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap ((b, c) -> b
forall a b. (a, b) -> a
fst ((b, c) -> b) -> (a -> (b, c)) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> (b, c)
abc) f b
fb
day2 :: Contravariant g => Day f g a -> g a
day2 :: forall (g :: * -> *) (f :: * -> *) a.
Contravariant g =>
Day f g a -> g a
day2 (Day f b
_ g c
gc a -> (b, c)
abc) = (a -> c) -> g c -> g a
forall a' a. (a' -> a) -> g a -> g a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap ((b, c) -> c
forall a b. (a, b) -> b
snd ((b, c) -> c) -> (a -> (b, c)) -> a -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> (b, c)
abc) g c
gc
diag :: f a -> Day f f a
diag :: forall (f :: * -> *) a. f a -> Day f f a
diag f a
fa = f a -> f a -> (a -> (a, a)) -> Day f f a
forall (f :: * -> *) (g :: * -> *) a b c.
f b -> g c -> (a -> (b, c)) -> Day f g a
Day f a
fa f a
fa ((a -> (a, a)) -> Day f f a) -> (a -> (a, a)) -> Day f f a
forall a b. (a -> b) -> a -> b
$ \a
a -> (a
a,a
a)
trans1 :: (forall x. f x -> g x) -> Day f h a -> Day g h a
trans1 :: forall (f :: * -> *) (g :: * -> *) (h :: * -> *) a.
(forall x. f x -> g x) -> Day f h a -> Day g h a
trans1 forall x. f x -> g x
fg (Day f b
fb h c
hc a -> (b, c)
abc) = g b -> h c -> (a -> (b, c)) -> Day g h a
forall (f :: * -> *) (g :: * -> *) a b c.
f b -> g c -> (a -> (b, c)) -> Day f g a
Day (f b -> g b
forall x. f x -> g x
fg f b
fb) h c
hc a -> (b, c)
abc
trans2 :: (forall x. g x -> h x) -> Day f g a -> Day f h a
trans2 :: forall (g :: * -> *) (h :: * -> *) (f :: * -> *) a.
(forall x. g x -> h x) -> Day f g a -> Day f h a
trans2 forall x. g x -> h x
gh (Day f b
fb g c
gc a -> (b, c)
abc) = f b -> h c -> (a -> (b, c)) -> Day f h a
forall (f :: * -> *) (g :: * -> *) a b c.
f b -> g c -> (a -> (b, c)) -> Day f g a
Day f b
fb (g c -> h c
forall x. g x -> h x
gh g c
gc) a -> (b, c)
abc