moduleDingo.Internal.CallbackTypes(CallbackState,CallbackM,CallbackT(..),WrapCallback(..),addCommand,augmentState,getCommands,mkSession,runCallbackT)whereimportControl.Monad.IO.Class(MonadIO(..))importControl.Monad.Trans.Class(MonadTrans(..))importControl.Monad.Trans.State.Strict(StateT,runStateT)importqualifiedControl.Monad.Trans.State.StrictasMTSimportqualifiedData.LabelasLimportData.Label.PureM(modify)importData.Monoid(Monoid(..))importData.Sequence(Seq,(|>))importqualifiedData.SequenceasSimportDingo.Internal.Base(Command(..))importDingo.Internal.SessionTypesimportDingo.ResourceBundle(ResourceBundle)-- Wrapper type to avoid cyclic type definition.dataWrapCallback=WrapCallback{unWrapCallback::CallbackM()}-- Define the session state.dataCallbackState=CallbackState{_csCommands::SeqCommand}-- Callback state is a monoid.instanceMonoidCallbackStatewheremempty=CallbackStateS.emptymappend(CallbackStates1)(CallbackStates2)=CallbackState$s1`mappend`s2-- Define the monad transformer.newtypeCallbackTma=CallbackT{unCallback::StateTCallbackStatema}deriving(Functor,Monad)-- CallbackT is a monad transformer.instanceMonadTransCallbackTwhereliftm=CallbackT$liftm-- CallbackT where the underlying monad is a MonadIO is also a MonadIO.instance(MonadIOm)=>MonadIO(CallbackTm)whereliftIO=lift.liftIO-- Type alias for convenience.typeCallbackM=CallbackT(SessionTWrapCallbackIO)-- Generate accessors.$(L.mkLabels[''CallbackState])-- Create an empty session state.mkSession::CallbackM()->[ResourceBundle]->SessionStateWrapCallbackmkSessionmain=mkSessionState(WrapCallbackmain)-- Sort the stream of commands appropriately.getCommands::CallbackState->SeqCommandgetCommands=L.getcsCommands-- Run a callback computation and return the stream of commands-- to send to the browser.runCallbackT::Monadm=>CallbackTma->m(a,CallbackState)runCallbackT(CallbackTcallback)=runStateTcallbackmempty-- Add a command to the callback.addCommand::Monadm=>Command->CallbackTm()addCommandcommand=CallbackT$modifycsCommands(|>command)-- Augment state with a different callback state.augmentState::Monadm=>CallbackState->CallbackTm()augmentStatest=CallbackT$MTS.modify$\s->s`mappend`st