module Data.ANum (ANum, unANum) where import Control.Applicative (Applicative, pure, (<*>), liftA, liftA2) newtype ANum f n = ANum (f n) deriving (Show) unANum :: ANum f n -> f n unANum (ANum x) = x instance (Functor f) => Functor (ANum f) where fmap f (ANum x) = ANum (fmap f x) instance (Applicative f) => Applicative (ANum f) where pure x = ANum (pure x) (ANum f) <*> (ANum x) = ANum (f <*> x) instance (Applicative f, Num n) => Num (ANum f n) where fromInteger = pure . fromInteger (*) = liftA2 (*) (+) = liftA2 (+) (-) = liftA2 (-) negate = liftA negate abs = liftA abs signum = liftA signum instance (Applicative f, Fractional n) => Fractional (ANum f n) where (/) = liftA2 (/) recip = liftA recip fromRational = pure . fromRational instance (Applicative f, Floating n) => Floating (ANum f n) where pi = pure pi exp = liftA exp sqrt = liftA sqrt log = liftA log (**) = liftA2 (**) logBase = liftA2 logBase sin = liftA sin tan = liftA tan cos = liftA cos asin = liftA asin atan = liftA atan acos = liftA acos sinh = liftA sinh tanh = liftA tanh cosh = liftA cosh asinh = liftA asinh atanh = liftA atanh acosh = liftA acosh