{-# LANGUAGE GeneralizedNewtypeDeriving
  #-}

{-|
Module      :  Data.Newtypes.PrettyDouble
Description :  A custom double for printing nice numbers in plots.
Copyright   :  Copyright (c) 2013 David Banas; all rights reserved World wide.
License     :  BSD3

Maintainer  :  capn.freako@gmail.com
Stability   :  Development
Portability :
-}
module Data.Newtypes.PrettyDouble (
    PrettyDouble (..)
) where

import Text.Printf

{-|
A custom double precision floating point type, which overides the 'Show'
and 'Eq' instances, in order to:

    * Limit precision to 3 places after the decimal.

    * Print ridiculously small numbers as simply zero.

    * Define equality as difference being less than some threshold.
-}
newtype PrettyDouble = PrettyDouble {
    uglyDouble :: Double
  } deriving (Num, Ord, Fractional, Floating, Real, RealFrac, RealFloat, Enum)

instance Show PrettyDouble where
    show = printf "%6.3g" . zeroThresh . uglyDouble
        where zeroThresh y =
                if abs y < 1.0e-10
                then 0.0
                else y

instance Eq PrettyDouble where
    z1' == z2' = abs (z1 - z2) < 1.0e-3
        where z1 = uglyDouble z1'
              z2 = uglyDouble z2'