number/src/Data/Number/Instances.hs
2015-08-20 20:40:13 +02:00

65 lines
1.7 KiB
Haskell

-- | Class instances for the continued fraction datatype
{-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}
module Data.Number.Instances where
import Data.Number.Types
import Data.Number.Internal
-- | transform a number applying a function ('Nat' -> 'Nat') to each
-- number preserving the sign.
instance Functor Continued where
fmap _ E = E
fmap f (M x) = M (fmap f x)
fmap f (x:|xs) = f x :| fmap f xs
-- | Basic Foldable instance implemented exactly as a list.
instance Foldable Continued where
foldr f z E = z
foldr f z (M x) = foldr f z x
foldr f z (x:|xs) = f x (foldr f z xs)
-- | Same as above.
instance Traversable Continued where
traverse _ E = pure E
traverse f (M x) = traverse f x
traverse f (x:|xs) = (:|) <$> f x <*> traverse f xs
-- | The sign is given by the first number of the fraction.
-- Other number are always considered positive.
instance Num Number where
(+) = biHom (0, 1, 1, 0, 1, 0, 0, 0)
(-) = biHom (0, 1, -1, 0, 1, 0, 0, 0)
(*) = biHom (0, 0, 0, 1, 1, 0, 0, 0)
abs (M x) = x
abs x = x
negate (M x) = x
negate x = M x
fromInteger = toNumber . fromIntegral
signum E = 0
signum (M _) = -1
signum _ = 1
-- | Allows conversion to a rational
instance Real Number where
toRational = fromNumber
-- | Allows division between 'Number's and conversion from a rational
instance Fractional Number where
(/) = biHom (0, 1, 0, 0, 0, 0, 1, 0)
fromRational = toNumber
-- Helpers --
-- | Convert a 'Number' into a 'RealFrac' number
fromNumber :: RealFrac a => Number -> a
fromNumber E = 0
fromNumber (M x) = negate (fromNumber x)
fromNumber (x :| E) = fromIntegral x
fromNumber (x :| xs) = fromIntegral x + 1 / (fromNumber xs)