{-
SMonad.hs
Copyright 2008 Matthew Sackman <matthew@wellquite.org>
This file is part of Session Types for Haskell.
Session Types for Haskell is free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Session Types for Haskell is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Session Types for Haskell.
If not, see <http://www.gnu.org/licenses/>.
-}{-# LANGUAGE KindSignatures, MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, UndecidableInstances #-}-- | Super magic Monads.moduleControl.Concurrent.Session.Base.SMonadwhereimportControl.Monad.StatenewtypeSChainmxya=SChain{runSChain::x->m(a,y)}-- | An extension of the typical Monad such that you track additional-- @from@ and @to@ parameters. Thus you can think of this like 'State'-- where the type of the 'State' varies.classSMonad(m::*->*->*->*)where(~>>)::mxya->myzb->mxzb(~>>=)::mxya->(a->myzb)->mxzbsreturn::a->mxxainfixl1~>>infixl1~>>=instance(Monadm)=>SMonad(SChainm)wheref~>>g=SChain$\x->do{(_,y)<-runSChainfx;runSChaingy}f~>>=g=SChain$\x->do{(a,y)<-runSChainfx;runSChain(ga)y}sreturna=SChain$\x->return(a,x)instance(Monadm)=>Monad(SChainmxx)wherem>>n=SChain$\x->do{~(_,y)<-runSChainmx;runSChainny}m>>=k=SChain$\x->do{~(a,y)<-runSChainmx;runSChain(ka)y}returna=SChain$\x->return(a,x)failstr=SChain$\_->failstrnewtypeSStateTsmxya=SStateT{runSStateT::s->mxy(a,s)}instance(SMonadm)=>SMonad(SStateTsm)wheref~>>g=SStateT$\s->runSStateTfs~>>=\(_,s')->runSStateTgs'f~>>=g=SStateT$\s->runSStateTfs~>>=\(a,s')->runSStateT(ga)s'sreturna=SStateT$\s->sreturn(a,s)classSMonadTranstwhereslift::(SMonadm)=>mxya->tmxyainstanceSMonadTrans(SStateTs)wheresliftf=SStateT$\s->f~>>=\a->sreturn(a,s)class(SMonadm)=>SMonadIOmwheresliftIO::IOa->mxxainstance(MonadIOm)=>SMonadIO(SChainm)wheresliftIOf=SChain$\x->do{a<-liftIOf;return(a,x)}class(SMonadm)=>SMonadStatesm|m->swheresget::mxxssput::s->mxx()instance(SMonadm)=>SMonadStates(SStateTsm)wheresget=SStateT$\s->sreturn(s,s)sputs=SStateT$\_->sreturn((),s)ssequence_::(SMonadm)=>[mxxa]->mxx()ssequence_[]=sreturn()ssequence_(f:fs)=f~>>ssequence_fsssequence::(SMonadm)=>[mxxa]->mxx[a]ssequence[]=sreturn[]ssequence(f:fs)=f~>>=\r->ssequencefs~>>=\rs->sreturn(r:rs)sjoin::(SMonadm)=>mxy(myzb)->mxzbsjoinf=f~>>=idsmapM::(SMonadm)=>(a->mxxb)->[a]->mxx[b]smapMflst=ssequence.mapf$lstsmapM_::(SMonadm)=>(a->mxxb)->[a]->mxx()smapM_flst=ssequence_.mapf$lst