{-# LANGUAGE CPP #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
#if __GLASGOW_HASKELL__ < 806
{-# LANGUAGE TypeInType #-}
#endif
module Control.Monad.Codensity
  ( Codensity(..)
  , lowerCodensity
  , codensityToAdjunction, adjunctionToCodensity
  , codensityToRan, ranToCodensity
  , codensityToComposedRep, composedRepToCodensity
  , wrapCodensity
  , improve
  
  , reset
  , shift
  ) where
import Control.Applicative
import Control.Monad (MonadPlus(..))
import qualified Control.Monad.Fail as Fail
import Control.Monad.Free
import Control.Monad.IO.Class
import Control.Monad.Reader.Class
import Control.Monad.State.Class
import Control.Monad.Trans.Class
import Data.Functor.Adjunction
import Data.Functor.Apply
import Data.Functor.Kan.Ran
import Data.Functor.Plus
import Data.Functor.Rep
import Data.Type.Equality (type (~~))
import GHC.Exts (TYPE)
newtype Codensity (m :: k -> TYPE rep) a = Codensity
  { forall k (m :: k -> *) a.
Codensity m a -> forall (b :: k). (a -> m b) -> m b
runCodensity :: forall b. (a -> m b) -> m b
  }
instance Functor (Codensity (k :: j -> TYPE rep)) where
  fmap :: forall a b. (a -> b) -> Codensity k a -> Codensity k b
fmap a -> b
f (Codensity forall (b :: j). (a -> k b) -> k b
m) = (forall (b :: j). (b -> k b) -> k b) -> Codensity k b
forall k (m :: k -> *) a.
(forall (b :: k). (a -> m b) -> m b) -> Codensity m a
Codensity (\b -> k b
k -> (a -> k b) -> k b
forall (b :: j). (a -> k b) -> k b
m (\a
x -> b -> k b
k (a -> b
f a
x)))
  {-# INLINE fmap #-}
instance Apply (Codensity (f :: k -> TYPE rep)) where
  <.> :: forall a b. Codensity f (a -> b) -> Codensity f a -> Codensity f b
(<.>) = Codensity f (a -> b) -> Codensity f a -> Codensity f b
forall a b. Codensity f (a -> b) -> Codensity f a -> Codensity f b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
(<*>)
  {-# INLINE (<.>) #-}
instance Applicative (Codensity (f :: k -> TYPE rep)) where
  pure :: forall a. a -> Codensity f a
pure a
x = (forall (b :: k). (a -> f b) -> f b) -> Codensity f a
forall k (m :: k -> *) a.
(forall (b :: k). (a -> m b) -> m b) -> Codensity m a
Codensity (\a -> f b
k -> a -> f b
k a
x)
  {-# INLINE pure #-}
  Codensity forall (b :: k). ((a -> b) -> f b) -> f b
f <*> :: forall a b. Codensity f (a -> b) -> Codensity f a -> Codensity f b
<*> Codensity forall (b :: k). (a -> f b) -> f b
g = (forall (b :: k). (b -> f b) -> f b) -> Codensity f b
forall k (m :: k -> *) a.
(forall (b :: k). (a -> m b) -> m b) -> Codensity m a
Codensity (\b -> f b
bfr -> ((a -> b) -> f b) -> f b
forall (b :: k). ((a -> b) -> f b) -> f b
f (\a -> b
ab -> (a -> f b) -> f b
forall (b :: k). (a -> f b) -> f b
g (\a
x -> b -> f b
bfr (a -> b
ab a
x))))
  {-# INLINE (<*>) #-}
instance Monad (Codensity (f :: k -> TYPE rep)) where
  return :: forall a. a -> Codensity f a
return = a -> Codensity f a
forall a. a -> Codensity f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
  {-# INLINE return #-}
  Codensity f a
m >>= :: forall a b. Codensity f a -> (a -> Codensity f b) -> Codensity f b
>>= a -> Codensity f b
k = (forall (b :: k). (b -> f b) -> f b) -> Codensity f b
forall k (m :: k -> *) a.
(forall (b :: k). (a -> m b) -> m b) -> Codensity m a
Codensity (\b -> f b
c -> Codensity f a -> forall (b :: k). (a -> f b) -> f b
forall k (m :: k -> *) a.
Codensity m a -> forall (b :: k). (a -> m b) -> m b
runCodensity Codensity f a
m (\a
a -> Codensity f b -> forall (b :: k). (b -> f b) -> f b
forall k (m :: k -> *) a.
Codensity m a -> forall (b :: k). (a -> m b) -> m b
runCodensity (a -> Codensity f b
k a
a) b -> f b
c))
  {-# INLINE (>>=) #-}
instance (f ~~ f', Fail.MonadFail f')
  => Fail.MonadFail (Codensity (f :: k -> TYPE rep)) where
  fail :: forall a. String -> Codensity f a
fail String
msg = (forall (b :: k). (a -> f b) -> f b) -> Codensity f a
forall k (m :: k -> *) a.
(forall (b :: k). (a -> m b) -> m b) -> Codensity m a
Codensity ((forall (b :: k). (a -> f b) -> f b) -> Codensity f a)
-> (forall (b :: k). (a -> f b) -> f b) -> Codensity f a
forall a b. (a -> b) -> a -> b
$ \ a -> f b
_ -> String -> f' b
forall a. String -> f' a
forall (m :: * -> *) a. MonadFail m => String -> m a
Fail.fail String
msg
  {-# INLINE fail #-}
instance (m ~~ m', MonadIO m')
  => MonadIO (Codensity (m :: k -> TYPE rep)) where
  liftIO :: forall a. IO a -> Codensity m a
liftIO = m' a -> Codensity m a
m' a -> Codensity m' a
forall (m :: * -> *) a. Monad m => m a -> Codensity m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m' a -> Codensity m a) -> (IO a -> m' a) -> IO a -> Codensity m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO a -> m' a
forall a. IO a -> m' a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO
  {-# INLINE liftIO #-}
instance MonadTrans Codensity where
  lift :: forall (m :: * -> *) a. Monad m => m a -> Codensity m a
lift m a
m = (forall b. (a -> m b) -> m b) -> Codensity m a
forall k (m :: k -> *) a.
(forall (b :: k). (a -> m b) -> m b) -> Codensity m a
Codensity (m a
m m a -> (a -> m b) -> m b
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=)
  {-# INLINE lift #-}
instance (v ~~ v', Alt v')
  => Alt (Codensity (v :: k -> TYPE rep)) where
  Codensity forall (b :: k). (a -> v b) -> v b
m <!> :: forall a. Codensity v a -> Codensity v a -> Codensity v a
<!> Codensity forall (b :: k). (a -> v b) -> v b
n = (forall (b :: k). (a -> v b) -> v b) -> Codensity v a
forall k (m :: k -> *) a.
(forall (b :: k). (a -> m b) -> m b) -> Codensity m a
Codensity (\a -> v b
k -> (a -> v b) -> v b
forall (b :: k). (a -> v b) -> v b
m a -> v b
k v' b -> v' b -> v' b
forall a. v' a -> v' a -> v' a
forall (f :: * -> *) a. Alt f => f a -> f a -> f a
<!> (a -> v b) -> v b
forall (b :: k). (a -> v b) -> v b
n a -> v b
k)
  {-# INLINE (<!>) #-}
instance (v ~~ v', Plus v') => Plus (Codensity (v :: k -> TYPE rep)) where
  zero :: forall a. Codensity v a
zero = (forall (b :: k). (a -> v b) -> v b) -> Codensity v a
forall k (m :: k -> *) a.
(forall (b :: k). (a -> m b) -> m b) -> Codensity m a
Codensity (v' b -> (a -> v b) -> v' b
forall a b. a -> b -> a
const v' b
forall a. v' a
forall (f :: * -> *) a. Plus f => f a
zero)
  {-# INLINE zero #-}
instance (v ~~ v', Alternative v')
  => Alternative (Codensity (v :: k -> TYPE rep)) where
  empty :: forall a. Codensity v a
empty = (forall (b :: k). (a -> v b) -> v b) -> Codensity v a
forall k (m :: k -> *) a.
(forall (b :: k). (a -> m b) -> m b) -> Codensity m a
Codensity (\a -> v b
_ -> v b
v' b
forall a. v' a
forall (f :: * -> *) a. Alternative f => f a
empty)
  {-# INLINE empty #-}
  Codensity forall (b :: k). (a -> v b) -> v b
m <|> :: forall a. Codensity v a -> Codensity v a -> Codensity v a
<|> Codensity forall (b :: k). (a -> v b) -> v b
n = (forall (b :: k). (a -> v b) -> v b) -> Codensity v a
forall k (m :: k -> *) a.
(forall (b :: k). (a -> m b) -> m b) -> Codensity m a
Codensity (\a -> v b
k -> (a -> v b) -> v b
forall (b :: k). (a -> v b) -> v b
m a -> v b
k v' b -> v' b -> v' b
forall a. v' a -> v' a -> v' a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (a -> v b) -> v b
forall (b :: k). (a -> v b) -> v b
n a -> v b
k)
  {-# INLINE (<|>) #-}
instance (v ~~ v', Alternative v')
   => MonadPlus (Codensity (v :: k -> TYPE rep))
lowerCodensity :: Applicative f => Codensity f a -> f a
lowerCodensity :: forall (f :: * -> *) a. Applicative f => Codensity f a -> f a
lowerCodensity Codensity f a
a = Codensity f a -> forall b. (a -> f b) -> f b
forall k (m :: k -> *) a.
Codensity m a -> forall (b :: k). (a -> m b) -> m b
runCodensity Codensity f a
a a -> f a
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
{-# INLINE lowerCodensity #-}
codensityToAdjunction :: Adjunction f g => Codensity g a -> g (f a)
codensityToAdjunction :: forall (f :: * -> *) (g :: * -> *) a.
Adjunction f g =>
Codensity g a -> g (f a)
codensityToAdjunction Codensity g a
r = Codensity g a -> forall b. (a -> g b) -> g b
forall k (m :: k -> *) a.
Codensity m a -> forall (b :: k). (a -> m b) -> m b
runCodensity Codensity g a
r a -> g (f a)
forall a. a -> g (f a)
forall (f :: * -> *) (u :: * -> *) a.
Adjunction f u =>
a -> u (f a)
unit
{-# INLINE codensityToAdjunction #-}
adjunctionToCodensity :: Adjunction f g => g (f a) -> Codensity g a
adjunctionToCodensity :: forall (f :: * -> *) (g :: * -> *) a.
Adjunction f g =>
g (f a) -> Codensity g a
adjunctionToCodensity g (f a)
f = (forall b. (a -> g b) -> g b) -> Codensity g a
forall k (m :: k -> *) a.
(forall (b :: k). (a -> m b) -> m b) -> Codensity m a
Codensity (\a -> g b
a -> (f a -> b) -> g (f a) -> g b
forall a b. (a -> b) -> g a -> g b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> g b) -> f a -> b
forall a b. (a -> g b) -> f a -> b
forall (f :: * -> *) (u :: * -> *) a b.
Adjunction f u =>
(a -> u b) -> f a -> b
rightAdjunct a -> g b
a) g (f a)
f)
{-# INLINE adjunctionToCodensity #-}
codensityToComposedRep :: Representable u => Codensity u a -> u (Rep u, a)
codensityToComposedRep :: forall (u :: * -> *) a.
Representable u =>
Codensity u a -> u (Rep u, a)
codensityToComposedRep (Codensity forall b. (a -> u b) -> u b
f) = (a -> u (Rep u, a)) -> u (Rep u, a)
forall b. (a -> u b) -> u b
f (\a
a -> (Rep u -> (Rep u, a)) -> u (Rep u, a)
forall a. (Rep u -> a) -> u a
forall (f :: * -> *) a. Representable f => (Rep f -> a) -> f a
tabulate ((Rep u -> (Rep u, a)) -> u (Rep u, a))
-> (Rep u -> (Rep u, a)) -> u (Rep u, a)
forall a b. (a -> b) -> a -> b
$ \Rep u
e -> (Rep u
e, a
a))
{-# INLINE codensityToComposedRep #-}
composedRepToCodensity :: Representable u => u (Rep u, a) -> Codensity u a
composedRepToCodensity :: forall (u :: * -> *) a.
Representable u =>
u (Rep u, a) -> Codensity u a
composedRepToCodensity u (Rep u, a)
hfa = (forall b. (a -> u b) -> u b) -> Codensity u a
forall k (m :: k -> *) a.
(forall (b :: k). (a -> m b) -> m b) -> Codensity m a
Codensity ((forall b. (a -> u b) -> u b) -> Codensity u a)
-> (forall b. (a -> u b) -> u b) -> Codensity u a
forall a b. (a -> b) -> a -> b
$ \a -> u b
k -> ((Rep u, a) -> b) -> u (Rep u, a) -> u b
forall a b. (a -> b) -> u a -> u b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(Rep u
e, a
a) -> u b -> Rep u -> b
forall a. u a -> Rep u -> a
forall (f :: * -> *) a. Representable f => f a -> Rep f -> a
index (a -> u b
k a
a) Rep u
e) u (Rep u, a)
hfa
{-# INLINE composedRepToCodensity #-}
codensityToRan :: Codensity g a -> Ran g g a
codensityToRan :: forall {k} (g :: k -> *) a. Codensity g a -> Ran g g a
codensityToRan (Codensity forall (b :: k). (a -> g b) -> g b
m) = (forall (b :: k). (a -> g b) -> g b) -> Ran g g a
forall {k} (g :: k -> *) (h :: k -> *) a.
(forall (b :: k). (a -> g b) -> h b) -> Ran g h a
Ran (a -> g b) -> g b
forall (b :: k). (a -> g b) -> g b
m
{-# INLINE codensityToRan #-}
ranToCodensity :: Ran g g a -> Codensity g a
ranToCodensity :: forall {k} (g :: k -> *) a. Ran g g a -> Codensity g a
ranToCodensity (Ran forall (b :: k). (a -> g b) -> g b
m) = (forall (b :: k). (a -> g b) -> g b) -> Codensity g a
forall k (m :: k -> *) a.
(forall (b :: k). (a -> m b) -> m b) -> Codensity m a
Codensity (a -> g b) -> g b
forall (b :: k). (a -> g b) -> g b
m
{-# INLINE ranToCodensity #-}
instance (m ~~ m', Functor f, MonadFree f m')
  => MonadFree f (Codensity (m :: k -> TYPE rep)) where
  wrap :: forall a. f (Codensity m a) -> Codensity m a
wrap f (Codensity m a)
t = (forall (b :: k). (a -> m b) -> m b) -> Codensity m a
forall k (m :: k -> *) a.
(forall (b :: k). (a -> m b) -> m b) -> Codensity m a
Codensity (\a -> m b
h -> f (m' b) -> m' b
forall a. f (m' a) -> m' a
forall (f :: * -> *) (m :: * -> *) a.
MonadFree f m =>
f (m a) -> m a
wrap ((Codensity m' a -> m' b) -> f (Codensity m' a) -> f (m' b)
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Codensity m' a
p -> Codensity m' a -> forall b. (a -> m' b) -> m' b
forall k (m :: k -> *) a.
Codensity m a -> forall (b :: k). (a -> m b) -> m b
runCodensity Codensity m' a
p a -> m b
a -> m' b
h) f (Codensity m a)
f (Codensity m' a)
t))
  {-# INLINE wrap #-}
instance (m ~~ m', MonadReader r m')
  => MonadState r (Codensity (m :: k -> TYPE rep)) where
  get :: Codensity m r
get = (forall (b :: k). (r -> m b) -> m b) -> Codensity m r
forall k (m :: k -> *) a.
(forall (b :: k). (a -> m b) -> m b) -> Codensity m a
Codensity (m r
m' r
forall r (m :: * -> *). MonadReader r m => m r
ask m r -> (r -> m b) -> m b
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=)
  {-# INLINE get #-}
  put :: r -> Codensity m ()
put r
s = (forall (b :: k). (() -> m b) -> m b) -> Codensity m ()
forall k (m :: k -> *) a.
(forall (b :: k). (a -> m b) -> m b) -> Codensity m a
Codensity (\() -> m b
k -> (r -> r) -> m' b -> m' b
forall a. (r -> r) -> m' a -> m' a
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local (r -> r -> r
forall a b. a -> b -> a
const r
s) (() -> m b
k ()))
  {-# INLINE put #-}
instance (m ~~ m', MonadReader r m')
  => MonadReader r (Codensity (m :: k -> TYPE rep)) where
  ask :: Codensity m r
ask = (forall (b :: k). (r -> m b) -> m b) -> Codensity m r
forall k (m :: k -> *) a.
(forall (b :: k). (a -> m b) -> m b) -> Codensity m a
Codensity (m r
m' r
forall r (m :: * -> *). MonadReader r m => m r
ask m r -> (r -> m b) -> m b
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=)
  {-# INLINE ask #-}
  local :: forall a. (r -> r) -> Codensity m a -> Codensity m a
local r -> r
f Codensity m a
m = (forall (b :: k). (a -> m b) -> m b) -> Codensity m a
forall k (m :: k -> *) a.
(forall (b :: k). (a -> m b) -> m b) -> Codensity m a
Codensity ((forall (b :: k). (a -> m b) -> m b) -> Codensity m a)
-> (forall (b :: k). (a -> m b) -> m b) -> Codensity m a
forall a b. (a -> b) -> a -> b
$ \a -> m b
c -> m' r
forall r (m :: * -> *). MonadReader r m => m r
ask m' r -> (r -> m' b) -> m' b
forall a b. m' a -> (a -> m' b) -> m' b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \r
r -> (r -> r) -> m' b -> m' b
forall a. (r -> r) -> m' a -> m' a
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local r -> r
f (m' b -> m' b) -> ((a -> m' b) -> m' b) -> (a -> m' b) -> m' b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Codensity m' a -> forall b. (a -> m' b) -> m' b
forall k (m :: k -> *) a.
Codensity m a -> forall (b :: k). (a -> m b) -> m b
runCodensity Codensity m a
Codensity m' a
m ((a -> m' b) -> m' b) -> (a -> m' b) -> m' b
forall a b. (a -> b) -> a -> b
$ (r -> r) -> m' b -> m' b
forall a. (r -> r) -> m' a -> m' a
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local (r -> r -> r
forall a b. a -> b -> a
const r
r) (m' b -> m' b) -> (a -> m' b) -> a -> m' b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> m b
a -> m' b
c
  {-# INLINE local #-}
improve :: Functor f => (forall m. MonadFree f m => m a) -> Free f a
improve :: forall (f :: * -> *) a.
Functor f =>
(forall (m :: * -> *). MonadFree f m => m a) -> Free f a
improve forall (m :: * -> *). MonadFree f m => m a
m = Codensity (Free f) a -> Free f a
forall (f :: * -> *) a. Applicative f => Codensity f a -> f a
lowerCodensity Codensity (Free f) a
forall (m :: * -> *). MonadFree f m => m a
m
{-# INLINE improve #-}
wrapCodensity :: (forall a. m a -> m a) -> Codensity m ()
wrapCodensity :: forall {k} (m :: k -> *).
(forall (a :: k). m a -> m a) -> Codensity m ()
wrapCodensity forall (a :: k). m a -> m a
f = (forall (b :: k). (() -> m b) -> m b) -> Codensity m ()
forall k (m :: k -> *) a.
(forall (b :: k). (a -> m b) -> m b) -> Codensity m a
Codensity (\() -> m b
k -> m b -> m b
forall (a :: k). m a -> m a
f (() -> m b
k ()))
reset :: Monad m => Codensity m a -> Codensity m a
reset :: forall (m :: * -> *) a. Monad m => Codensity m a -> Codensity m a
reset = m a -> Codensity m a
forall (m :: * -> *) a. Monad m => m a -> Codensity m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> Codensity m a)
-> (Codensity m a -> m a) -> Codensity m a -> Codensity m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Codensity m a -> m a
forall (f :: * -> *) a. Applicative f => Codensity f a -> f a
lowerCodensity
shift :: Applicative m => (forall b. (a -> m b) -> Codensity m b) -> Codensity m a
shift :: forall (m :: * -> *) a.
Applicative m =>
(forall b. (a -> m b) -> Codensity m b) -> Codensity m a
shift forall b. (a -> m b) -> Codensity m b
f = (forall b. (a -> m b) -> m b) -> Codensity m a
forall k (m :: k -> *) a.
(forall (b :: k). (a -> m b) -> m b) -> Codensity m a
Codensity ((forall b. (a -> m b) -> m b) -> Codensity m a)
-> (forall b. (a -> m b) -> m b) -> Codensity m a
forall a b. (a -> b) -> a -> b
$ Codensity m b -> m b
forall (f :: * -> *) a. Applicative f => Codensity f a -> f a
lowerCodensity (Codensity m b -> m b)
-> ((a -> m b) -> Codensity m b) -> (a -> m b) -> m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> m b) -> Codensity m b
forall b. (a -> m b) -> Codensity m b
f