public
Created

  • Download Gist
Number.hs
Haskell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
{-# LANGUAGE DeriveDataTypeable #-}
-- |
-- Module : Data.Attoparsec.Text.Number
-- Copyright : Bryan O'Sullivan 2011, Bas van Dijk 2011
-- License : BSD3
--
-- Maintainer : felipe.lessa@gmail.com
-- Stability : experimental
-- Portability : unknown
--
-- A simple number type, useful for parsing both exact and inexact
-- quantities without losing precision.
module Data.Attoparsec.Text.Number
(
Number(..)
) where
 
import Control.DeepSeq (NFData(rnf))
import Data.Data (Data)
import Data.Typeable (Typeable)
import Data.Ratio ((%))
 
-- | A numeric type that can represent integers accurately, and
-- floating point numbers to the precision of a 'Double'.
data Number = I !Integer
| R !Rational
deriving (Typeable, Data)
 
instance Show Number where
show (I a) = show a
show (R a) = show a
 
instance NFData Number where
rnf (I _) = ()
rnf (R _) = ()
{-# INLINE rnf #-}
 
binop :: (Integer -> Integer -> a)
-> (Rational -> Rational -> a)
-> (Number -> Number -> a)
binop _ r (R a) (R b) = r a b
binop i _ (I a) (I b) = i a b
binop _ r (R a) (I b) = r a (fromIntegral b)
binop _ r (I a) (R b) = r (fromIntegral a) b
{-# INLINE binop #-}
 
instance Eq Number where
(==) = binop (==) (==)
{-# INLINE (==) #-}
 
(/=) = binop (/=) (/=)
{-# INLINE (/=) #-}
 
instance Ord Number where
(<) = binop (<) (<)
{-# INLINE (<) #-}
 
(<=) = binop (<=) (<=)
{-# INLINE (<=) #-}
 
(>) = binop (>) (>)
{-# INLINE (>) #-}
 
(>=) = binop (>=) (>=)
{-# INLINE (>=) #-}
 
compare = binop compare compare
{-# INLINE compare #-}
 
instance Num Number where
(+) = binop (((I$!).) . (+)) (((R$!).) . (+))
{-# INLINE (+) #-}
 
(-) = binop (((I$!).) . (-)) (((R$!).) . (-))
{-# INLINE (-) #-}
 
(*) = binop (((I$!).) . (*)) (((R$!).) . (*))
{-# INLINE (*) #-}
 
abs (I a) = I $! abs a
abs (R a) = R $! abs a
{-# INLINE abs #-}
 
negate (I a) = I $! negate a
negate (R a) = R $! negate a
{-# INLINE negate #-}
 
signum (I a) = I $! signum a
signum (R a) = R $! signum a
{-# INLINE signum #-}
 
fromInteger = (I$!) . fromInteger
{-# INLINE fromInteger #-}
 
instance Real Number where
toRational (I a) = fromIntegral a
toRational (R a) = a
{-# INLINE toRational #-}
 
instance Fractional Number where
fromRational = (R$!)
{-# INLINE fromRational #-}
 
(/) = binop (((R$!).) . (%))
(((R$!).) . (/))
{-# INLINE (/) #-}
 
recip (I a) = R $! recip (fromIntegral a)
recip (R a) = R $! recip a
{-# INLINE recip #-}
 
instance RealFrac Number where
properFraction (I a) = (fromIntegral a,0)
properFraction (R a) = case properFraction a of
(i,d) -> (i,R d)
{-# INLINE properFraction #-}
truncate (I a) = fromIntegral a
truncate (R a) = truncate a
{-# INLINE truncate #-}
round (I a) = fromIntegral a
round (R a) = round a
{-# INLINE round #-}
ceiling (I a) = fromIntegral a
ceiling (R a) = ceiling a
{-# INLINE ceiling #-}
floor (I a) = fromIntegral a
floor (R a) = floor a
{-# INLINE floor #-}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.