65 lines
1.7 KiB
Haskell
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)
|