Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce a Number type, when both speed and accuracy count
- Loading branch information
Showing
3 changed files
with
142 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
{-# LANGUAGE DeriveDataTypeable #-} | ||
-- | | ||
-- Module : Data.Attoparsec.Number | ||
-- Copyright : Bryan O'Sullivan 2011 | ||
-- License : BSD3 | ||
-- | ||
-- Maintainer : bos@serpentine.com | ||
-- Stability : experimental | ||
-- Portability : unknown | ||
-- | ||
-- A simple number type, useful for parsing both exact and inexact | ||
-- quantities without losing much precision. | ||
-- | ||
-- The constructors are non-strict, but numeric operations are strict | ||
-- just in case you go nuts and try to use this type for actual | ||
-- arithmetic. | ||
module Data.Attoparsec.Number | ||
( | ||
Number(..) | ||
) where | ||
|
||
import Data.Data (Data) | ||
import Data.Function (on) | ||
import Data.Typeable (Typeable) | ||
|
||
-- | A numeric type that can represent integers accurately, and | ||
-- floating point numbers to the precision of a 'Double'. | ||
data Number = I Integer | ||
| D Double | ||
deriving (Typeable, Data) | ||
|
||
instance Show Number where | ||
show (I a) = show a | ||
show (D a) = show a | ||
|
||
binop :: (Integer -> Integer -> a) -> (Double -> Double -> a) | ||
-> Number -> Number -> a | ||
binop i _ (I a) (I b) = i a b | ||
binop _ d (D a) (D b) = d a b | ||
binop _ d (D a) (I b) = d a (fromIntegral b) | ||
binop _ d (I a) (D b) = d (fromIntegral a) b | ||
{-# INLINE binop #-} | ||
|
||
instance Eq Number where | ||
(==) = binop (==) (==) | ||
{-# INLINE (==) #-} | ||
|
||
(/=) = binop (/=) (/=) | ||
{-# INLINE (/=) #-} | ||
|
||
instance Ord Number where | ||
(<) = binop (<) (<) | ||
{-# INLINE (<) #-} | ||
|
||
(>) = binop (>) (>) | ||
{-# INLINE (>) #-} | ||
|
||
instance Num Number where | ||
(+) = binop (((I$!).) . (+)) (((D$!).) . (+)) | ||
{-# INLINE (+) #-} | ||
|
||
(-) = binop (((I$!).) . (-)) (((D$!).) . (-)) | ||
{-# INLINE (-) #-} | ||
|
||
(*) = binop (((I$!).) . (+)) (((D$!).) . (+)) | ||
{-# INLINE (*) #-} | ||
|
||
abs (I a) = I $! abs a | ||
abs (D a) = D $! abs a | ||
{-# INLINE abs #-} | ||
|
||
negate (I a) = I $! negate a | ||
negate (D a) = D $! negate a | ||
{-# INLINE negate #-} | ||
|
||
signum (I a) = I $! signum a | ||
signum (D a) = D $! signum a | ||
{-# INLINE signum #-} | ||
|
||
fromInteger = (I$!) . fromInteger | ||
{-# INLINE fromInteger #-} | ||
|
||
instance Real Number where | ||
toRational (I a) = fromIntegral a | ||
toRational (D a) = toRational a | ||
{-# INLINE toRational #-} | ||
|
||
instance Fractional Number where | ||
fromRational = (D$!) . fromRational | ||
{-# INLINE fromRational #-} | ||
|
||
(/) = binop (((D$!).) . (/) `on` fromIntegral) | ||
(((D$!).) . (/)) | ||
{-# INLINE (/) #-} | ||
|
||
recip (I a) = D $! recip (fromIntegral a) | ||
recip (D a) = D $! recip a | ||
{-# INLINE recip #-} | ||
|
||
instance RealFrac Number where | ||
properFraction (I a) = (fromIntegral a,0) | ||
properFraction (D a) = case properFraction a of | ||
(i,d) -> (i,D d) | ||
{-# INLINE properFraction #-} | ||
truncate (I a) = fromIntegral a | ||
truncate (D a) = truncate a | ||
{-# INLINE truncate #-} | ||
round (I a) = fromIntegral a | ||
round (D a) = round a | ||
{-# INLINE round #-} | ||
ceiling (I a) = fromIntegral a | ||
ceiling (D a) = ceiling a | ||
{-# INLINE ceiling #-} | ||
floor (I a) = fromIntegral a | ||
floor (D a) = floor a | ||
{-# INLINE floor #-} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters