{-# LANGUAGE GeneralizedNewtypeDeriving #-}{- |
A wrapper that provides instances of Haskell 98 and NumericPrelude
numeric type classes
for types that have Haskell 98 instances.
-}moduleMathObj.Wrapper.Haskell98whereimportqualifiedAlgebra.AbsoluteasAbsoluteimportqualifiedAlgebra.AdditiveasAdditiveimportqualifiedAlgebra.AlgebraicasAlgebraicimportqualifiedAlgebra.FieldasFieldimportqualifiedAlgebra.IntegralDomainasIntegralimportqualifiedAlgebra.PrincipalIdealDomainasPIDimportqualifiedAlgebra.RealFieldasRealFieldimportqualifiedAlgebra.RealIntegralasRealIntegralimportqualifiedAlgebra.RealRingasRealRingimportqualifiedAlgebra.RealTranscendentalasRealTransimportqualifiedAlgebra.RingasRingimportqualifiedAlgebra.ToIntegerasToIntegerimportqualifiedAlgebra.ToRationalasToRationalimportqualifiedAlgebra.TranscendentalasTransimportqualifiedAlgebra.UnitsasUnitsimportqualifiedAlgebra.ZeroTestableasZeroTestableimportqualifiedNumber.RatioasRatioimportqualifiedAlgebra.RealRing98asRealRing98importData.Ix(Ix,)importData.Tuple.HT(mapPair,){- |
This makes a type usable in the NumericPrelude framework
that was initially implemented for Haskell98 typeclasses.
E.g. if @a@ is in class 'Num',
then @T a@ is both in class 'Num' and in 'Ring.C'.
You can even lift container types.
If @Polynomial a@ is in 'Num' for all types @a@ that are in 'Num',
then @T (Polynomial (MathObj.Wrapper.NumericPrelude.T a))@
is in 'Ring.C' for all types @a@ that are in 'Ring.C'.
-}newtypeTa=Consaderiving(Show,Eq,Ord,Ix,Bounded,Enum,Num,Integral,Fractional,Floating,Real,RealFrac,RealFloat){-# INLINE lift1 #-}lift1::(a->b)->Ta->Tblift1f(Consa)=Cons(fa){-# INLINE lift2 #-}lift2::(a->b->c)->Ta->Tb->Tclift2f(Consa)(Consb)=Cons(fab)instanceFunctorTwhere{-# INLINE fmap #-}fmapf(Consa)=Cons(fa)instanceNuma=>Additive.C(Ta)wherezero=0(+)=lift2(+)(-)=lift2(-)negate=lift1negateinstance(Numa)=>Ring.C(Ta)wherefromInteger=Cons.fromInteger(*)=lift2(*)(^)an=lift1(^n)ainstance(Fractionala)=>Field.C(Ta)wherefromRational'r=Cons(fromRational(Ratio.toRational98r))(/)=lift2(/)recip=lift1recip(^-)an=lift1(^^n)ainstance(Floatinga)=>Algebraic.C(Ta)wheresqrt=lift1sqrt(^/)ar=lift1(**fromRational(Ratio.toRational98r))arootna=lift1(**recip(fromIntegern))ainstance(Floatinga)=>Trans.C(Ta)wherepi=Conspilog=lift1logexp=lift1explogBase=lift2logBase(**)=lift2(**)cos=lift1costan=lift1tansin=lift1sinacos=lift1acosatan=lift1atanasin=lift1asincosh=lift1coshtanh=lift1tanhsinh=lift1sinhacosh=lift1acoshatanh=lift1atanhasinh=lift1asinhinstance(Integrala)=>Integral.C(Ta)wherediv=lift2divmod=lift2moddivMod(Consa)(Consb)=mapPair(Cons,Cons)(divModab)instance(Integrala)=>Units.C(Ta)whereisUnit=unimplemented"isUnit"stdAssociate=unimplemented"stdAssociate"stdUnit=unimplemented"stdUnit"stdUnitInv=unimplemented"stdUnitInv"instance(Integrala)=>PID.C(Ta)wheregcd=gcdlcm=lcminstance(Eqa,Numa)=>ZeroTestable.C(Ta)whereisZero(Consa)=a==0instance(Numa)=>Absolute.C(Ta)whereabs=abssignum=signuminstance(RealFraca)=>RealRing.C(Ta)wheresplitFraction(Consa)=mapPair(Ring.fromInteger,Cons)(RealRing98.fixSplitFraction(properFractiona))fraction(Consa)=Cons(RealRing98.fixFraction(RealRing98.signedFractiona))ceiling(Consa)=Ring.fromInteger(ceilinga)floor(Consa)=Ring.fromInteger(floora)truncate(Consa)=Ring.fromInteger(truncatea)round(Consa)=Ring.fromInteger(rounda)instance(RealFraca)=>RealField.C(Ta)whereinstance(RealFloata)=>RealTrans.C(Ta)whereatan2=atan2instance(Integrala)=>RealIntegral.C(Ta)wherequot=lift2quotrem=lift2remquotRem(Consa)(Consb)=mapPair(Cons,Cons)(quotRemab)instance(Integrala)=>ToInteger.C(Ta)wheretoInteger(Consa)=toIntegerainstance(Reala)=>ToRational.C(Ta)wheretoRational(Consa)=Field.fromRational(toRationala)unimplemented::String->aunimplementedname=error(name++"cannot be implemented in terms of Haskell98 type classes")