#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
#endif
#include "kan-extensions-common.h"
module Data.Functor.Yoneda
( Yoneda(..)
, liftYoneda, lowerYoneda
, maxF, minF, maxM, minM
, yonedaToRan, ranToYoneda
) where
import Control.Applicative
import Control.Monad (MonadPlus(..), liftM)
import Control.Monad.Fix
import Control.Monad.Free.Class
import Control.Monad.Trans.Class
import Control.Comonad
import Control.Comonad.Trans.Class
import Data.Distributive
import Data.Foldable
import Data.Functor.Adjunction
import Data.Functor.Bind
import Data.Functor.Classes
import Data.Functor.Extend
import Data.Functor.Identity
import Data.Functor.Kan.Ran
import Data.Functor.Plus
import Data.Functor.Rep
import Data.Semigroup.Foldable
import Data.Semigroup.Traversable
import Data.Traversable
import Text.Read hiding (lift)
import Prelude hiding (sequence, lookup, zipWith)
newtype Yoneda f a = Yoneda { runYoneda :: forall b. (a -> b) -> f b }
liftYoneda :: Functor f => f a -> Yoneda f a
liftYoneda a = Yoneda (\f -> fmap f a)
lowerYoneda :: Yoneda f a -> f a
lowerYoneda (Yoneda f) = f id
yonedaToRan :: Yoneda f a -> Ran Identity f a
yonedaToRan (Yoneda m) = Ran (m . fmap runIdentity)
ranToYoneda :: Ran Identity f a -> Yoneda f a
ranToYoneda (Ran m) = Yoneda (m . fmap Identity)
instance Functor (Yoneda f) where
fmap f m = Yoneda (\k -> runYoneda m (k . f))
instance Apply f => Apply (Yoneda f) where
Yoneda m <.> Yoneda n = Yoneda (\f -> m (f .) <.> n id)
instance Applicative f => Applicative (Yoneda f) where
pure a = Yoneda (\f -> pure (f a))
Yoneda m <*> Yoneda n = Yoneda (\f -> m (f .) <*> n id)
instance Foldable f => Foldable (Yoneda f) where
foldMap f = foldMap f . lowerYoneda
instance Foldable1 f => Foldable1 (Yoneda f) where
foldMap1 f = foldMap1 f . lowerYoneda
instance Traversable f => Traversable (Yoneda f) where
traverse f = fmap liftYoneda . traverse f . lowerYoneda
instance Traversable1 f => Traversable1 (Yoneda f) where
traverse1 f = fmap liftYoneda . traverse1 f . lowerYoneda
instance Distributive f => Distributive (Yoneda f) where
collect f = liftYoneda . collect (lowerYoneda . f)
instance Representable g => Representable (Yoneda g) where
type Rep (Yoneda g) = Rep g
tabulate = liftYoneda . tabulate
index = index . lowerYoneda
instance Adjunction f g => Adjunction (Yoneda f) (Yoneda g) where
unit = liftYoneda . fmap liftYoneda . unit
counit (Yoneda m) = counit (m lowerYoneda)
instance Show1 f => Show1 (Yoneda f) where
#if LIFTED_FUNCTOR_CLASSES
liftShowsPrec sp sl d (Yoneda f) =
showsUnaryWith (liftShowsPrec sp sl) "liftYoneda" d (f id)
#else
showsPrec1 d (Yoneda f) = showParen (d > 10) $
showString "liftYoneda " . showsPrec1 11 (f id)
#endif
instance (Read1 f, Functor f) => Read1 (Yoneda f) where
#if LIFTED_FUNCTOR_CLASSES
liftReadsPrec rp rl = readsData $
readsUnaryWith (liftReadsPrec rp rl) "liftYoneda" liftYoneda
#else
readsPrec1 d = readParen (d > 10) $ \r' ->
[ (liftYoneda f, t)
| ("liftYoneda", s) <- lex r'
, (f, t) <- readsPrec1 11 s
]
#endif
instance Show (f a) => Show (Yoneda f a) where
showsPrec d (Yoneda f) = showParen (d > 10) $
showString "liftYoneda " . showsPrec 11 (f id)
instance (Functor f, Read (f a)) => Read (Yoneda f a) where
#ifdef __GLASGOW_HASKELL__
readPrec = parens $ prec 10 $ do
Ident "liftYoneda" <- lexP
liftYoneda <$> step readPrec
#else
readsPrec d = readParen (d > 10) $ \r' ->
[ (liftYoneda f, t)
| ("liftYoneda", s) <- lex r'
, (f, t) <- readsPrec 11 s
]
#endif
infixl 0 `on1`
on1 :: (g a -> g b -> c) -> (forall x. f x -> g x) -> f a -> f b -> c
(.*.) `on1` f = \x y -> f x .*. f y
instance Eq1 f => Eq1 (Yoneda f) where
#if LIFTED_FUNCTOR_CLASSES
liftEq eq = liftEq eq `on1` lowerYoneda
#else
eq1 = eq1 `on1` lowerYoneda
#endif
instance Ord1 f => Ord1 (Yoneda f) where
#if LIFTED_FUNCTOR_CLASSES
liftCompare cmp = liftCompare cmp `on1` lowerYoneda
#else
compare1 = compare1 `on1` lowerYoneda
#endif
instance (Eq1 f, Eq a) => Eq (Yoneda f a) where
(==) = eq1
instance (Ord1 f, Ord a) => Ord (Yoneda f a) where
compare = compare1
maxF :: (Functor f, Ord (f a)) => Yoneda f a -> Yoneda f a -> Yoneda f a
Yoneda f `maxF` Yoneda g = liftYoneda $ f id `max` g id
minF :: (Functor f, Ord (f a)) => Yoneda f a -> Yoneda f a -> Yoneda f a
Yoneda f `minF` Yoneda g = liftYoneda $ f id `max` g id
maxM :: (Monad m, Ord (m a)) => Yoneda m a -> Yoneda m a -> Yoneda m a
Yoneda f `maxM` Yoneda g = lift $ f id `max` g id
minM :: (Monad m, Ord (m a)) => Yoneda m a -> Yoneda m a -> Yoneda m a
Yoneda f `minM` Yoneda g = lift $ f id `min` g id
instance Alt f => Alt (Yoneda f) where
Yoneda f <!> Yoneda g = Yoneda (\k -> f k <!> g k)
instance Plus f => Plus (Yoneda f) where
zero = Yoneda $ const zero
instance Alternative f => Alternative (Yoneda f) where
empty = Yoneda $ const empty
Yoneda f <|> Yoneda g = Yoneda (\k -> f k <|> g k)
instance Bind m => Bind (Yoneda m) where
Yoneda m >>- k = Yoneda (\f -> m id >>- \a -> runYoneda (k a) f)
instance Monad m => Monad (Yoneda m) where
#if __GLASGOW_HASKELL__ < 710
return a = Yoneda (\f -> return (f a))
#endif
Yoneda m >>= k = Yoneda (\f -> m id >>= \a -> runYoneda (k a) f)
instance MonadFix m => MonadFix (Yoneda m) where
mfix f = lift $ mfix (lowerYoneda . f)
instance MonadPlus m => MonadPlus (Yoneda m) where
mzero = Yoneda (const mzero)
Yoneda f `mplus` Yoneda g = Yoneda (\k -> f k `mplus` g k)
instance MonadTrans Yoneda where
lift a = Yoneda (\f -> liftM f a)
instance (Functor f, MonadFree f m) => MonadFree f (Yoneda m) where
wrap = lift . wrap . fmap lowerYoneda
instance Extend w => Extend (Yoneda w) where
extended k (Yoneda m) = Yoneda (\f -> extended (f . k . liftYoneda) (m id))
instance Comonad w => Comonad (Yoneda w) where
extend k (Yoneda m) = Yoneda (\f -> extend (f . k . liftYoneda) (m id))
extract = extract . lowerYoneda
instance ComonadTrans Yoneda where
lower = lowerYoneda