{-# OPTIONS -fno-implicit-prelude #-}moduleNumber.ResidueClass.ReaderwhereimportqualifiedNumber.ResidueClassasResimportqualifiedAlgebra.PrincipalIdealDomainasPIDimportqualifiedAlgebra.IntegralDomainasIntegralimportqualifiedAlgebra.RingasRingimportqualifiedAlgebra.AdditiveasAdditiveimportPreludeBaseimportNumericPreludeimportControl.Monad(liftM2,liftM4)-- import Control.Monad.Reader (MonadReader)importqualifiedPreludeasPimportqualifiedNumericPreludeasNP{- |
T is a Reader monad but does not need functional dependencies
like that from the Monad Template Library.
-}newtypeTab=Cons{toFunc::a->b}concrete::a->Tab->bconcretem(Consr)=rmfromRepresentative::(Integral.Ca)=>a->TaafromRepresentative=Cons.modgetZero::(Additive.Ca)=>TaagetZero=Cons$constAdditive.zerogetOne::(Ring.Ca)=>TaagetOne=Cons$constNP.onefromInteger::(Integral.Ca)=>Integer->TaafromInteger=fromRepresentative.NP.fromIntegerinstanceMonad(Ta)where(Consx)>>=y=Cons(\r->toFunc(y(xr))r)return=Cons.constgetAdd::Integral.Ca=>Ta(a->a->a)getAdd=ConsRes.addgetSub::Integral.Ca=>Ta(a->a->a)getSub=ConsRes.subgetNeg::Integral.Ca=>Ta(a->a)getNeg=ConsRes.neggetAdditiveVars::Integral.Ca=>Ta(a,a->a->a,a->a->a,a->a)getAdditiveVars=liftM4(,,,)getZerogetAddgetSubgetNeggetMul::Integral.Ca=>Ta(a->a->a)getMul=ConsRes.mulgetRingVars::Integral.Ca=>Ta(a,a->a->a)getRingVars=liftM2(,)getOnegetMulgetDivide::PID.Ca=>Ta(a->a->a)getDivide=ConsRes.dividegetRecip::PID.Ca=>Ta(a->a)getRecip=ConsRes.recipgetFieldVars::PID.Ca=>Ta(a->a->a,a->a)getFieldVars=liftM2(,)getDividegetRecipmonadExample::PID.Ca=>Ta[a]monadExample=do(zero',(+~),(-~),negate')<-getAdditiveVars(one',(*~))<-getRingVars((/~),recip')<-getFieldVarsletthree=one'+one'+one'-- is easier if only NP.fromInteger is visibleletseven=three+three+one'return[zero'*~three,one'/~three,recip'three,three*~seven,one'+~three+~seven,zero'-~three,negate'three+~seven]runExample::[Integer]runExample=letthree=one+one+oneeleven=three+three+three+one+oneinconcreteelevenmonadExample