{-# LANGUAGE GeneralizedNewtypeDeriving, TypeFamilies, UndecidableInstances, FlexibleInstances, MultiParamTypeClasses #-}-- | A module implementing the array abstraction on a purely functional IntMap. When attempting to debug a complex array-using algorithm, it may sometimes be useful to use a less segfault-prone implementation. In addition, the execXXX commands allow the final state of the 'IntMap' to be returned.moduleControl.Monad.Array.IntMap(IntMapT,evalIntMapT,execIntMapT,execIntMapT_,evalIntMapT_,IntMapM,execIntMapM,evalIntMapM,execIntMapM_,evalIntMapM_)whereimportControl.Monad.Array.ClassimportControl.Monad.StateimportControl.Monad.ReaderimportControl.Monad.Writer.ClassimportControl.Monad.TransimportqualifiedData.IntMapasIMimportData.IntMap(IntMap)importControl.Monad-- | An array transformer with an 'IntMap' on the back end. Provides decent performance while retaining a purely functional back end. /Note:/ resizing operations have no effect, and the 'askSize' operation returns the number of associations in the 'IntMap'.newtypeIntMapTema=IntMapT{runIMapT::ReaderTe(StateT(IntMape)m)a}deriving(Monad,MonadFix,MonadPlus,MonadIO,MonadWriterw)-- | Basic monad version of 'IntMapT'.newtypeIntMapMea=IntMapM{runIMapM::ReaderTe(State(IntMape))a}deriving(Monad,MonadFix)-- | Evaluates an 'IntMapT' computation with the specified default element.evalIntMapT::Monadm=>e->IntMapTema->maevalIntMapTdm=evalStateT(runReaderT(runIMapTm)d)IM.empty-- | Evaluates an 'IntMapT' computation with the specified default element, returning the final 'IntMap'.execIntMapT::Monadm=>e->IntMapTema->m(IntMape)execIntMapTdm=execStateT(runReaderT(runIMapTm)d)IM.emptyevalIntMapM::e->IntMapMea->aevalIntMapMdm=evalState(runReaderT(runIMapMm)d)IM.emptyexecIntMapM::e->IntMapMea->IntMapeexecIntMapMdm=execState(runReaderT(runIMapMm)d)IM.empty-- | Evaluates an 'IntMapT' computation with no default element specified.evalIntMapT_::Monadm=>IntMapTema->maevalIntMapT_=evalIntMapTemptyElement-- | Evaluates an 'IntMapT' computation with no default element specified, returning the final 'IntMap'.execIntMapT_::Monadm=>IntMapTema->m(IntMape)execIntMapT_=execIntMapTemptyElementevalIntMapM_::IntMapMea->aevalIntMapM_=evalIntMapMemptyElementexecIntMapM_::IntMapMea->IntMapeexecIntMapM_=execIntMapMemptyElementemptyElement::eemptyElement=error"Undefined array element"instanceMonadTrans(IntMapTe)wherelift=IntMapT.lift.liftinstanceMonadm=>MonadArray(IntMapTem)wheretypeArrayElem(IntMapTem)=ereadAti=IntMapT$gets(IM.lookupi)>>=maybeaskreturnwriteAtix=IntMapT$modify(IM.insertix)askSize=IntMapT$getsIM.sizeensureSize_=return()askElems=IntMapT$getsIM.elemsaskAssocs=IntMapT$getsIM.toListinstanceMonadArray(IntMapMe)wheretypeArrayElem(IntMapMe)=ereadAti=IntMapM$gets(IM.lookupi)>>=maybeaskreturnwriteAtix=IntMapM$modify(IM.insertix)askSize=IntMapM$getsIM.sizeensureSize_=return()askElems=IntMapM$getsIM.elemsaskAssocs=IntMapM$getsIM.toListinstanceMonadStatesm=>MonadStates(IntMapTem)whereget=liftgetput=lift.putinstanceMonadReaderrm=>MonadReaderr(IntMapTem)whereask=liftasklocalf=(lift.localf.return=<<)