hunk ./doc/html/monad-ran/Control-Monad-Ran.html 22
->monad-ran-0.0.6: Implementations of common monads and monad transformers as right Kan extensionsmonad-ran-0.0.7: Fast implementations of monads and monad transformers using right Kan extensions
{-# LANGUAGE RankNTypes, FlexibleInstances, FlexibleContexts, TypeFamilies, MultiParamTypeClasses, MagicHash, UnboxedTuples, UndecidableInstances #-}
+-- Finding the right Kan extension
+
+moduleControl.Monad.Ran
+(
+-- * The Yoneda Lemma
+Yoneda(..)
+-- * The codensity monad of a functor
+,Codensity(..)
+-- * A right Kan extension monad transformer
+,Ran(..)
+-- * Representing monads as right Kan extensions
+,RMonad
+,G
+,H
+,liftRan
+,lowerRan
+)where
+
+importData.Monoid
+importData.Maybe(maybe)
+importControl.Applicative
+importControl.Functor.Pointed
+importControl.Monad
+importControl.Monad.Yoneda
+importControl.Monad.Codensity
+importControl.Monad.Identity
+importControl.Monad.Cont
+importControl.Monad.State
+importControl.Monad.Error
+importControl.Monad.Reader
+importControl.Monad.Writer
+importControl.Monad.RWS
+
+importGHC.Prim
+importGHC.IOBasehiding(liftIO)
+importGHC.Conc
+importGHC.ST
+
+-- | A right Kan extension transformer for a monad
+dataRanma=Ran{getRan::forallb.(a->Gmb)->Hmb}
hunk ./doc/html/monad-ran/src/Control-Monad-Ran.html 51
-instanceFunctor(Codensityk)where
-fmapfm=Codensity(\k->getCodensitym(k.f))
-
-instanceApplicative(Codensityf)where
-pure=return
-(<*>)=ap
-
-instanceMonad(Codensityf)where
-returnx=Codensity(\k->kx)
-m>>=k=Codensity(\c->getCodensitym(\a->getCodensity(ka)c))
-
-instanceMonadTransCodensitywhere
-liftm=Codensity(m>>=)
-
-runCodensity::Monadm=>Codensityma->ma
-runCodensity=flipgetCodensityreturn
-
-runCodensityApp::Applicativef=>Codensityfa->fa
-runCodensityApp=flipgetCodensitypure
-
--- .. Pointed
-
-dataRanma=Ran{getRan::forallb.(a->Gmb)->Hmb}
+classRanIsofwhere
+typeGf::*->*
+typeHf::*->*
+liftRan::fa->Ranfa
+lowerRan::Ranfa->fa
+
+instanceRanIsof=>Functor(Ranf)where
+fmapfm=Ran(\k->getRanm(k.f))
+
+returnCodensity::(RanIsom,Gm~Hm)=>a->Ranma
+returnCodensitya=Ran(\k->ka)
+
+bindCodensity::(RanIsom,Gm~Hm)=>Ranma->(a->Ranmb)->Ranmb
+bindCodensity(Ranm)k=Ran(\c->m(\a->getRan(ka)c))
+
+apCodensity::(RanIsom,Gm~Hm)=>Ranm(a->b)->Ranma->Ranmb
+apCodensity(Ranf)(Ranx)=Ran(\k->f(\f'->x(k.f')))
+
+class(Monad(Ranf),Monadf,RanIsof)=>RMonadf
+instance(Monad(Ranf),Monadf,RanIsof)=>RMonadf
+
+class(Applicative(Ranf),Applicativef,RanIsof)=>RApplicativef
+instance(Applicative(Ranf),Applicativef,RanIsof)=>RApplicativef
hunk ./doc/html/monad-ran/src/Control-Monad-Ran.html 75
-classMonadf=>RMonadfwhere
-typeGf::*->*
-typeHf::*->*
-toRan::fa->Ranfa
-fromRan::Ranfa->fa
-
---class RMonadTrans t where
--- liftR :: RMonad m => RanT m a -> RanT (t m) a
-
--- utility bifunctors for definitions below
-typeHom=(->)
-type(:->)=ReaderT
-
-dataErrorHbr=ErrorH{getErrorH::(b->r)->r}
-dataErrorTHbmr=ErrorTH{getErrorTH::(b->Gmr)->Hmr}
-
--- Yoneda Identity
--- forall o. (a -> o) -> o
-instanceRMonadIdentitywhere
-typeGIdentity=Identity
-typeHIdentity=Identity
-toRanm=Ran(m>>=)
-fromRan=flipgetRanIdentity
-
--- Yoneda Endo
--- forall o. (a -> o) -> o -> o
-instanceRMonadMaybewhere
-typeGMaybe=Identity
-typeHMaybe=Endo
-toRan(Justx)=Ran(\k->Endo(\_->runIdentity(kx)))
-toRanNothing=Ran(\_->Endoid)
-fromRan(Ranf)=appEndo(f(Identity.Just))Nothing
-
--- Yoneda (ErrorH b)
--- forall o. (a -> o) -> (b -> o) -> o
-instanceErrorb=>RMonad(Eitherb)where
-typeG(Eitherb)=Identity
-typeH(Eitherb)=ErrorHb
+-- The codensity monad as a right Kan extension of a functor along itself
+-- Many state-like monads can be CPS transformed into a codensity monad.
+instanceRanIso(Codensityf)where
+typeG(Codensityf)=f
+typeH(Codensityf)=f
+liftRan(Codensityf)=Ranf
+lowerRan(Ranf)=Codensityf
+
+ranCodensity::Ran(Codensityf)a->Codensityfa
+ranCodensity=lowerRan
+
+codensityRan::Codensityfa->Ran(Codensityf)a
+codensityRan=liftRan
+
+liftRanCodensity::Monadf=>fa->Ran(Codensityf)a
+liftRanCodensityf=Ran(f>>=)
+
+lowerRanCodensity::Monadf=>Ran(Codensityf)a->fa
+lowerRanCodensity(Ranf)=freturn
+
+instancePointed(Ran(Codensityf))where
+point=returnCodensity
+
+instanceApplicative(Ran(Codensityf))where
+pure=returnCodensity
+(<*>)=apCodensity
+
+instanceMonad(Ran(Codensityf))where
+return=returnCodensity
+(>>=)=bindCodensity
+
+instanceMonadPlusf=>Alternative(Ran(Codensityf))where
+empty=liftRanmzero
+m<|>n=liftRan(lowerRanm`mplus`lowerRann)
+
+instanceMonadPlusf=>MonadPlus(Ran(Codensityf))where
+mzero=liftRanmzero
+m`mplus`n=liftRan(lowerRanm`mplus`lowerRann)
hunk ./doc/html/monad-ran/src/Control-Monad-Ran.html 114
--- Yoneda (ErrorTH b m)
--- forall o. (a -> G m o) -> (b -> G m o) -> H m o
-instance(RMonadm,Errorb)=>RMonad(ErrorTbm)where
-typeG(ErrorTbm)=Gm
-typeH(ErrorTbm)=ErrorTHbm
-
--- Yoneda f
--- forall o. (a -> o) -> f o
-instanceMonadf=>RMonad(Yonedaf)where
-typeG(Yonedaf)=Identity
-typeH(Yonedaf)=f
+instanceMonadIOf=>MonadIO(Ran(Codensityf))where
+liftIOf=Ran(liftIOf>>=)
+
+instanceMonadStatesm=>MonadStates(Ran(Codensitym))where
+get=Ran(get>>=)
+puts=Ran(puts>>=)
+
+instanceMonadWriterwm=>MonadWriterw(Ran(Codensitym))where
+tellw=Ran(tellw>>=)
+listen=liftRanCodensity.listen.lowerRanCodensity
+pass=liftRanCodensity.pass.lowerRanCodensity
hunk ./doc/html/monad-ran/src/Control-Monad-Ran.html 126
--- Codensity f
--- forall o. (a -> f o) -> f o
-instanceRMonad(Codensityf)where
-typeG(Codensityf)=f
-typeH(Codensityf)=f
-
--- Yoneda (Reader r)
--- forall o. (a -> o) -> r -> o
-instanceRMonad(Readere)where
-typeG(Readere)=Identity
-typeH(Readere)=Home
-
--- embedded as CPS'd State to avoid superfluous 'mappend mempty' calls
--- specialized Codensity (Reader w)
--- forall o. (a -> w -> o) -> w -> o
-instanceMonoidw=>RMonad(Writerw)where
-typeG(Writerw)=Homw
-typeH(Writerw)=Homw
--- forall o. (a -> w -> o) -> o
--- type H (Writer w) = Identity
-
--- Codensity (Reader s)
--- forall o. (a -> s -> o) -> s -> o
-instanceRMonad(States)where
-typeG(States)=Homs
-typeH(States)=Homs
-
--- Codensity (Const r)
--- (a -> r) -> r
-instanceRMonad(Contr)where
-typeG(Contr)=Constr
-typeH(Contr)=Constr
-
--- forall o. (a -> G m o) -> r -> H m o
-instanceRMonadm=>RMonad(ReaderTem)where
-typeG(ReaderTem)=Gm
-typeH(ReaderTem)=e:->Hm
-
--- forall o. (a -> w -> G m o) -> H m o
-instance(Monoidw,RMonadm)=>RMonad(WriterTwm)where
-typeG(WriterTwm)=w:->Gm
-typeH(WriterTwm)=Hm
-
--- forall o. (a -> s -> G m o) -> s -> H m o
-instanceRMonadm=>RMonad(StateTsm)where
-typeG(StateTsm)=s:->Gm
-typeH(StateTsm)=s:->Hm
-
--- (a -> G m r) -> H m r
-dataConstTrfa=ConstT{getConstT::fr}
-instanceRMonadm=>RMonad(ContTrm)where
-typeG(ContTrm)=ConstTr(Gm)
-typeH(ContTrm)=ConstTr(Hm)
+instanceMonadReaderrm=>MonadReaderr(Ran(Codensitym))where
+ask=Ran(ask>>=)
+localf=liftRanCodensity.localf.lowerRanCodensity
+
+instanceMonadRWSrwsm=>MonadRWSrws(Ran(Codensitym))
+
+instanceMonadFixm=>MonadFix(Ran(Codensitym))where
+mfixf=liftRanCodensity$mfix(lowerRanCodensity.f)
+
+instanceMonadErrorem=>MonadErrore(Ran(Codensitym))where
+throwErrore=Ran(throwErrore>>=)
+m`catchError`h=liftRanCodensity(lowerRanCodensitym`catchError`(lowerRanCodensity.h))
+
+-- TODO: the other instances for Ran (Codensity f)
+-- MonadIO, MonadState, etc.
+
+-- Yoneda Identity a ~ Codensity Identity a ~ forall o. (a -> o) -> o
+instanceRanIsoIdentitywhere
+typeGIdentity=Identity
+typeHIdentity=Identity
+liftRanm=Ran(m>>=)
+lowerRan=flipgetRanIdentity
+
+instancePointed(RanIdentity)where
+point=returnCodensity
+
+instanceApplicative(RanIdentity)where
+pure=returnCodensity
+(<*>)=apCodensity
+
+instanceMonad(RanIdentity)where
+return=returnCodensity
+(>>=)=bindCodensity
+
+newtypeWorldwa=World{runWorld::State#w->a}
+
+-- homegrown STret with flopped arguments
+dataSTret'sa=STret'a(State#s)
+
+liftRanWorld::(Gm~Worldw,Hm~Worldw)=>(State#w->(#State#w,a#))->Ranma
+liftRanWorldf=Ran(\k->World(\w->casefwof(#w',a#)->runWorld(ka)w'))
+
+-- viewpatterned to eliminate named temporaries:
+-- liftRanWorld f = Ran (\k -> World (\(f -> (# w, (runWorld . k -> j) #)) -> j w))
+
+lowerRanWorld::(Gm~Worldw,Hm~Worldw)=>Ranma->State#w->(#State#w,a#)
+lowerRanWorld(Ranr)w=caserunWorld(r(World.STret'))wof
+STret'bw''->(#w'',b#)
+
+-- Represent IO as the codensity of the RealWorld
+instanceRanIsoIOwhere
+typeGIO=WorldRealWorld
+typeHIO=WorldRealWorld
+liftRan(IOs)=liftRanWorlds
+lowerRans=IO(lowerRanWorlds)
+
+instanceApplicative(RanIO)where
+pure=returnCodensity
+(<*>)=apCodensity
+
+instanceMonad(RanIO)where
+return=returnCodensity
+(>>=)=bindCodensity
+
+instanceMonadIO(RanIO)where
+liftIO=liftRan
+
+-- Represent ST s as the codensity of the world s
+instanceRanIso(STs)where
+typeG(STs)=Worlds
+typeH(STs)=Worlds
+liftRan(STs)=liftRanWorlds
+lowerRanr=ST(lowerRanWorldr)
+
+instanceApplicative(Ran(STs))where
+pure=returnCodensity
+(<*>)=apCodensity
+
+instanceMonad(Ran(STs))where
+return=returnCodensity
+(>>=)=bindCodensity
+
+-- todo make a MonadST class
+
+-- Represent STM as the codensity of the RealWorld
+instanceRanIsoSTMwhere
+typeGSTM=WorldRealWorld
+typeHSTM=WorldRealWorld
+liftRan(STMs)=liftRanWorlds
+lowerRanr=STM(lowerRanWorldr)
+
+instanceApplicative(RanSTM)where
+pure=returnCodensity
+(<*>)=apCodensity
+
+instanceMonad(RanSTM)where
+return=returnCodensity
+(>>=)=bindCodensity
+
+-- TODO: make a MonadSTM class
+
+-- Yoneda Endo a ~ forall o. (a -> o) -> o -> o ~ forall o. (a -> Identity o) -> Endo o
+-- note Endo is not a Hask Functor and Maybe is not a Codensity monad, so this is trickier
+instanceRanIsoMaybewhere
+typeGMaybe=Identity
+typeHMaybe=Endo
+liftRan=maybemzeroreturn
+lowerRanf=appEndo(getRanf(Identity.return))mzero
+
+instanceMonad(RanMaybe)where
+returnx=Ran(\k->Endo(\_->runIdentity(kx)))
+Rang>>=f=Ran(\k->Endo(\z->appEndo(g(\a->Identity(appEndo(getRan(fa)k)z)))z))
+fail_=mzero
+
+instanceApplicative(RanMaybe)where
+purex=Ran(\k->Endo(\_->runIdentity(kx)))
+Ranf<*>Rang=Ran(\k->Endo(\z->appEndo(f(\f'->Identity(appEndo(g(k.f'))z)))z))
+
+instanceMonadPlus(RanMaybe)where
+mzero=Ran(\_->Endoid)
+Ranm`mplus`Rann=Ran(\k->Endo(\z->appEndo(mk)(appEndo(nk)z)))
+
+-- as per Maybe, this Monoid turns a semigroup into a monoid
+instanceMonoida=>Monoid(RanMaybea)where
+mempty=mzero
+Rana`mappend`Ranb=Ran(\k->Endo(\z->appEndo(a(\a'->Identity(appEndo(b(k.mappenda'))z)))z))
+
+type(:->)=ReaderT
+
+dataErrorHeo=ErrorH{getErrorH::(e->o)->o}
+dataErrorTHemo=ErrorTH{getErrorTH::(e->Gmo)->Hmo}
+
+
+-- Yoneda (ErrorH e) ~ forall o. (a -> o) -> (e -> o) -> o ~ forall o. (a -> Identity o) -> (e -> o) -> o ~ forall o. (a -> Identity o) -> ErrorH e o
+instanceErrore=>RanIso(Eithere)where
+typeG(Eithere)=Identity
+typeH(Eithere)=ErrorHe
+liftRan(Righta)=Ran(\k->ErrorH(\_->runIdentity(ka)))
+liftRan(Leftx)=Ran(\_->ErrorH(\e->ex))
+lowerRan=eitherRanLeftRight
+
+eitherRan::(e->b)->(a->b)->Ran(Eithere)a->b
+eitherRanfg(Ranm)=getErrorH(m(Identity.g))f
+
+instanceErrore=>Monad(Ran(Eithere))where
+returnx=Ran(\k->ErrorH(\_->runIdentity(kx)))
+fail=throwError.strMsg
+Rang>>=f=Ran(\k->ErrorH(\z->getErrorH(g(\a->Identity(getErrorH(getRan(fa)k)z)))z))
+
+instanceErrore=>MonadErrore(Ran(Eithere))where
+throwErrorx=Ran(\_->ErrorH(\e->ex))
+-- catchError f h = Ran (\k -> ErrorH (\e -> getErrorH (getRan f k) e))
+-- catchError :: Ran (Either e) a -> (e -> Ran (Either e) a -> Ran (Either e) a
+Ranm`catchError`h=Ran(\k->ErrorH(\z->getErrorH(mk)(\e->getErrorH(getRan(he)k)z)))
+
+instanceErrore=>MonadPlus(Ran(Eithere))where
+mzero=throwErrornoMsg
+Ranm`mplus`Rann=Ran(\k->ErrorH(\z->getErrorH(mk)(\_->getErrorH(nk)z)))
+
+{-
+-- Yoneda (ErrorTH b m)
+-- forall o. (a -> G m o) -> (b -> G m o) -> H m o
+-- forall o. (a -> G m o) -> H m ((b -> G m o) -> o) ?
+instance (RMonad m, Error b) => RMonad (ErrorT b m) where
+ type G (ErrorT b m) = G m
+ type H (ErrorT b m) = ErrorTH b m
+
+
+-- Codensity f
+-- forall o. (a -> f o) -> f o
+instance RMonad (Codensity f) where
+ type G (Codensity f) = f
+ type H (Codensity f) = f
+ liftRan (Codensity f) = Ran f
+ lowerRan (Ran f) = Codensity f
+
+-- Yoneda (Reader r)
+-- forall o. (a -> o) -> r -> o
+instance RMonad (Reader e) where
+ type G (Reader e) = Identity
+ type H (Reader e) = Reader e
+ liftRan m = Ran (\f -> liftM (runIdentity . f) m)
+ lowerRan (Ran f) = f Identity
+
+-- embedded as CPS'd State to avoid superfluous 'mappend mempty' calls
+-- specialized Codensity (Reader w)
+-- forall o. (a -> w -> o) -> w -> o
+instance Monoid w => RMonad (Writer w) where
+ type G (Writer w) = (->) w
+ type H (Writer w) = (->) w
+ liftRan (Writer (a,w')) = Ran (\f w -> f a (w `mappend` w'))
+ lowerRan (Ran f) = Writer (f (,) mempty)
+ -- forall o. (a -> w -> o) -> o
+ -- type H (Writer w) = Identity
+
+-- Codensity (Reader s)
+-- forall o. (a -> s -> o) -> s -> o
+instance RMonad (State s) where
+ type G (State s) = (->) s
+ type H (State s) = (->) s
+ liftRan (State g) = Ran (\f -> uncurry f . g)
+ lowerRan (Ran f) = State (f (,))
+
+-- Codensity (Const r)
+-- (a -> r) -> r
+instance RMonad (Cont r) where
+ type G (Cont r) = Const r
+ type H (Cont r) = Const r
+
+-- forall o. (a -> G m o) -> r -> H m o
+instance RMonad m => RMonad (ReaderT e m) where
+ type G (ReaderT e m) = G m
+ type H (ReaderT e m) = e :-> H m
+
+-- forall o. (a -> w -> G m o) -> H m o
+-- forall o. (a -> G m (w -> o)) -> H m (w -> o) ?
+instance (Monoid w, RMonad m) => RMonad (WriterT w m) where
+ type G (WriterT w m) = w :-> G m
+ type H (WriterT w m) = H m
+
+-- forall o. (a -> s -> G m o) -> s -> H m o
+-- forall o. (a -> G m (s -> o)) -> H m (s -> o) ?
+instance RMonad m => RMonad (StateT s m) where
+ type G (StateT s m) = s :-> G m
+ type H (StateT s m) = s :-> H m
+
+-- (a -> G m r) -> H m r
+data ConstT r f a = ConstT { getConstT :: f r }
+instance RMonad m => RMonad (ContT r m) where
+ type G (ContT r m) = ConstT r (G m)
+ type H (ContT r m) = ConstT r (H m)
+-}
+
+
+
+-- Yoneda lemma as a right Kan extension along the identity functor
+instanceRanIso(Yonedaf)where
+typeG(Yonedaf)=Identity
+typeH(Yonedaf)=f
+liftRan(Yonedaf)=Ran(\b->f(runIdentity.b))
+lowerRan(Ranf)=Yoneda(\b->f(Identity.b))
+
+ranYoneda::Ran(Yonedaf)a->Yonedafa
+ranYoneda=lowerRan
+
+yonedaRan::Yonedafa->Ran(Yonedaf)a
+yonedaRan=liftRan
+
+instancePointedf=>Pointed(Ran(Yonedaf))where
+point=liftRan.point
+
+instanceApplicativef=>Applicative(Ran(Yonedaf))where
+pure=liftRan.pure
+m<*>n=liftRan(lowerRanm<*>lowerRann)
+
+instanceAlternativef=>Alternative(Ran(Yonedaf))where
+empty=liftRanempty
+m<|>n=liftRan(lowerRanm<|>lowerRann)
+
+instanceMonadf=>Monad(Ran(Yonedaf))where
+return=liftRan.return
+m>>=k=liftRan(lowerRanm>>=lowerRan.k)
+
+instanceMonadPlusf=>MonadPlus(Ran(Yonedaf))where
+mzero=liftRanmzero
+m`mplus`n=liftRan(lowerRanm`mplus`lowerRann)
+
+instanceMonadReaderrf=>MonadReaderr(Ran(Yonedaf))where
+ask=liftRanask
+localf=liftRan.localf.lowerRan
+
+instanceMonadWriterwf=>MonadWriterw(Ran(Yonedaf))where
+tell=liftRan.tell
+listen=liftRan.listen.lowerRan
+pass=liftRan.pass.lowerRan
+
+instanceMonadStatesf=>MonadStates(Ran(Yonedaf))where
+get=liftRanget
+put=liftRan.put
+
+instanceMonadIOf=>MonadIO(Ran(Yonedaf))where
+liftIO=liftRan.liftIO
+
+instanceMonadRWSrwsf=>MonadRWSrws(Ran(Yonedaf))
+
+instanceMonadErroref=>MonadErrore(Ran(Yonedaf))where
+throwError=liftRan.throwError
+Ranf`catchError`h=Ran(\k->fk`catchError`\e->getRan(he)k)
+
+instanceMonadFixm=>MonadFix(Ran(Yonedam))where
+mfixf=Ran(\k->liftM(runIdentity.k)$mfix(\a->getRan(fa)Identity))
addfile ./doc/html/monad-ran/src/Control-Monad-Yoneda.html
hunk ./doc/html/monad-ran/src/Control-Monad-Yoneda.html 1
+
+
+
+
+Control/Monad/Yoneda.hs
+
+
+
+