module Data.Vinyl.Functor where
import Control.Applicative
class Presheaf f where
contramap :: (a -> b) -> (f b -> f a)
newtype Lift op f g x = Lift { runLift :: op (f x) (g x) }
instance (Functor f, Functor g) => Functor (Lift (,) f g) where
fmap f (Lift (x, y)) = Lift (fmap f x, fmap f y)
instance (Functor f, Functor g) => Functor (Lift Either f g) where
fmap f (Lift (Left x)) = Lift . Left . fmap f $ x
fmap f (Lift (Right x)) = Lift . Right . fmap f $ x
instance (Presheaf f, Presheaf g) => Presheaf (Lift (,) f g) where
contramap f (Lift (x, y)) = Lift (contramap f x, contramap f y)
instance (Presheaf f, Presheaf g) => Presheaf (Lift Either f g) where
contramap f (Lift (Left x)) = Lift . Left . contramap f $ x
contramap f (Lift (Right x)) = Lift . Right . contramap f $ x
instance (Applicative f, Applicative g) => Applicative (Lift (,) f g) where
pure x = Lift (pure x, pure x)
Lift (f, g) <*> Lift (x, y) = Lift (f <*> x, g <*> y)
instance (Presheaf f, Functor g) => Functor (Lift (->) f g) where
fmap f (Lift ηx) = Lift $ fmap f . ηx . contramap f
instance (Functor f, Presheaf g) => Presheaf (Lift (->) f g) where
contramap f (Lift ηx) = Lift $ contramap f . ηx . fmap f