{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -fenable-rewrite-rules #-}
module Data.Functor.Contravariant.Rep
(
Representable(..)
, tabulated
, contramapRep
) where
import Control.Monad.Reader
import Data.Functor.Contravariant
import Data.Functor.Product
import Data.Profunctor
import Data.Proxy
import GHC.Generics hiding (Rep)
import Prelude hiding (lookup)
class Contravariant f => Representable f where
type Rep f :: *
tabulate :: (a -> Rep f) -> f a
index :: f a -> a -> Rep f
contramapWithRep :: (b -> Either a (Rep f)) -> f a -> f b
contramapWithRep b -> Either a (Rep f)
f f a
p = (b -> Rep f) -> f b
forall (f :: * -> *) a. Representable f => (a -> Rep f) -> f a
tabulate ((b -> Rep f) -> f b) -> (b -> Rep f) -> f b
forall a b. (a -> b) -> a -> b
$ (a -> Rep f) -> (Rep f -> Rep f) -> Either a (Rep f) -> Rep f
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (f a -> a -> Rep f
forall (f :: * -> *) a. Representable f => f a -> a -> Rep f
index f a
p) Rep f -> Rep f
forall a. a -> a
id (Either a (Rep f) -> Rep f)
-> (b -> Either a (Rep f)) -> b -> Rep f
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> Either a (Rep f)
f
{-# RULES
"tabulate/index" forall t. tabulate (index t) = t #-}
tabulated :: (Representable f, Representable g, Profunctor p, Functor h)
=> p (f a) (h (g b)) -> p (a -> Rep f) (h (b -> Rep g))
tabulated :: p (f a) (h (g b)) -> p (a -> Rep f) (h (b -> Rep g))
tabulated = ((a -> Rep f) -> f a)
-> (h (g b) -> h (b -> Rep g))
-> p (f a) (h (g b))
-> p (a -> Rep f) (h (b -> Rep g))
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap (a -> Rep f) -> f a
forall (f :: * -> *) a. Representable f => (a -> Rep f) -> f a
tabulate ((g b -> b -> Rep g) -> h (g b) -> h (b -> Rep g)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap g b -> b -> Rep g
forall (f :: * -> *) a. Representable f => f a -> a -> Rep f
index)
{-# INLINE tabulated #-}
contramapRep :: Representable f => (a -> b) -> f b -> f a
contramapRep :: (a -> b) -> f b -> f a
contramapRep a -> b
f = (a -> Rep f) -> f a
forall (f :: * -> *) a. Representable f => (a -> Rep f) -> f a
tabulate ((a -> Rep f) -> f a) -> (f b -> a -> Rep f) -> f b -> f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((b -> Rep f) -> (a -> b) -> a -> Rep f
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f) ((b -> Rep f) -> a -> Rep f)
-> (f b -> b -> Rep f) -> f b -> a -> Rep f
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f b -> b -> Rep f
forall (f :: * -> *) a. Representable f => f a -> a -> Rep f
index
instance Representable Proxy where
type Rep Proxy = ()
tabulate :: (a -> Rep Proxy) -> Proxy a
tabulate a -> Rep Proxy
_ = Proxy a
forall k (t :: k). Proxy t
Proxy
index :: Proxy a -> a -> Rep Proxy
index Proxy a
Proxy a
_ = ()
contramapWithRep :: (b -> Either a (Rep Proxy)) -> Proxy a -> Proxy b
contramapWithRep b -> Either a (Rep Proxy)
_ Proxy a
Proxy = Proxy b
forall k (t :: k). Proxy t
Proxy
instance Representable (Op r) where
type Rep (Op r) = r
tabulate :: (a -> Rep (Op r)) -> Op r a
tabulate = (a -> Rep (Op r)) -> Op r a
forall a b. (b -> a) -> Op a b
Op
index :: Op r a -> a -> Rep (Op r)
index = Op r a -> a -> Rep (Op r)
forall a b. Op a b -> b -> a
getOp
instance Representable Predicate where
type Rep Predicate = Bool
tabulate :: (a -> Rep Predicate) -> Predicate a
tabulate = (a -> Rep Predicate) -> Predicate a
forall a. (a -> Bool) -> Predicate a
Predicate
index :: Predicate a -> a -> Rep Predicate
index = Predicate a -> a -> Rep Predicate
forall a. Predicate a -> a -> Bool
getPredicate
instance (Representable f, Representable g) => Representable (Product f g) where
type Rep (Product f g) = (Rep f, Rep g)
tabulate :: (a -> Rep (Product f g)) -> Product f g a
tabulate a -> Rep (Product f g)
f = f a -> g a -> Product f g a
forall k (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product f g a
Pair ((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 f) -> (a -> (Rep f, Rep g)) -> a -> Rep f
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> (Rep f, Rep g)
a -> Rep (Product f g)
f)) ((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 ((Rep f, Rep g) -> Rep g) -> (a -> (Rep f, Rep g)) -> a -> Rep g
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> (Rep f, Rep g)
a -> Rep (Product f g)
f))
index :: Product f g a -> a -> Rep (Product f g)
index (Pair f a
f g a
g) a
a = (f a -> a -> Rep f
forall (f :: * -> *) a. Representable f => f a -> a -> Rep f
index f a
f a
a, g a -> a -> Rep g
forall (f :: * -> *) a. Representable f => f a -> a -> Rep f
index g a
g a
a)
contramapWithRep :: (b -> Either a (Rep (Product f g)))
-> Product f g a -> Product f g b
contramapWithRep b -> Either a (Rep (Product f g))
h (Pair f a
f g a
g) = f b -> g b -> Product f g b
forall k (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product f g a
Pair
((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 (((Rep f, Rep g) -> Rep f)
-> Either a (Rep f, Rep g) -> Either a (Rep f)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Rep f, Rep g) -> Rep f
forall a b. (a, b) -> a
fst (Either a (Rep f, Rep g) -> Either a (Rep f))
-> (b -> Either a (Rep f, Rep g)) -> b -> Either a (Rep f)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> Either a (Rep f, Rep g)
b -> Either a (Rep (Product f g))
h) f a
f)
((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 (((Rep f, Rep g) -> Rep g)
-> Either a (Rep f, Rep g) -> Either a (Rep g)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Rep f, Rep g) -> Rep g
forall a b. (a, b) -> b
snd (Either a (Rep f, Rep g) -> Either a (Rep g))
-> (b -> Either a (Rep f, Rep g)) -> b -> Either a (Rep g)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> Either a (Rep f, Rep g)
b -> Either a (Rep (Product f g))
h) g a
g)
instance Representable U1 where
type Rep U1 = ()
tabulate :: (a -> Rep U1) -> U1 a
tabulate a -> Rep U1
_ = U1 a
forall k (p :: k). U1 p
U1
index :: U1 a -> a -> Rep U1
index U1 a
U1 a
_ = ()
contramapWithRep :: (b -> Either a (Rep U1)) -> U1 a -> U1 b
contramapWithRep b -> Either a (Rep U1)
_ U1 a
U1 = U1 b
forall k (p :: k). U1 p
U1
instance (Representable f, Representable g) => Representable (f :*: g) where
type Rep (f :*: g) = (Rep f, Rep g)
tabulate :: (a -> Rep (f :*: g)) -> (:*:) f g a
tabulate a -> Rep (f :*: g)
f = (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 f) -> (a -> (Rep f, Rep g)) -> a -> Rep f
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> (Rep f, Rep g)
a -> Rep (f :*: g)
f) f a -> g a -> (:*:) f g a
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: (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 ((Rep f, Rep g) -> Rep g) -> (a -> (Rep f, Rep g)) -> a -> Rep g
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> (Rep f, Rep g)
a -> Rep (f :*: g)
f)
index :: (:*:) f g a -> a -> Rep (f :*: g)
index (f a
f :*: g a
g) a
a = (f a -> a -> Rep f
forall (f :: * -> *) a. Representable f => f a -> a -> Rep f
index f a
f a
a, g a -> a -> Rep g
forall (f :: * -> *) a. Representable f => f a -> a -> Rep f
index g a
g a
a)
contramapWithRep :: (b -> Either a (Rep (f :*: g))) -> (:*:) f g a -> (:*:) f g b
contramapWithRep b -> Either a (Rep (f :*: g))
h (f a
f :*: g a
g) =
(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 (((Rep f, Rep g) -> Rep f)
-> Either a (Rep f, Rep g) -> Either a (Rep f)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Rep f, Rep g) -> Rep f
forall a b. (a, b) -> a
fst (Either a (Rep f, Rep g) -> Either a (Rep f))
-> (b -> Either a (Rep f, Rep g)) -> b -> Either a (Rep f)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> Either a (Rep f, Rep g)
b -> Either a (Rep (f :*: g))
h) f a
f f b -> g b -> (:*:) f g b
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: (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 (((Rep f, Rep g) -> Rep g)
-> Either a (Rep f, Rep g) -> Either a (Rep g)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Rep f, Rep g) -> Rep g
forall a b. (a, b) -> b
snd (Either a (Rep f, Rep g) -> Either a (Rep g))
-> (b -> Either a (Rep f, Rep g)) -> b -> Either a (Rep g)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> Either a (Rep f, Rep g)
b -> Either a (Rep (f :*: g))
h) g a
g