-----------------------------------------------------------------------------
-- Copyright 2019, Advise-Me project team. This file is distributed under 
-- the terms of the Apache License 2.0. For more information, see the files
-- "LICENSE.txt" and "NOTICE.txt", which are included in the distribution.
-----------------------------------------------------------------------------
-- |
-- Maintainer  :  bastiaan.heeren@ou.nl
-- Stability   :  provisional
-- Portability :  portable (depends on ghc)
--
-----------------------------------------------------------------------------

module Bayes.Probability (Probability, toDouble, fromDouble) where

data Probability = P { toDouble :: !Double }
 deriving (Eq, Ord)

instance Show Probability where
   show (P a) = display 1 (toRational a*100) ++ "%"

instance Num Probability where
   P a + P b     = P (a + b)
   P a - P b     = P (a - b)
   P a * P b     = P (a * b)
   abs (P a)     = P (abs a)
   signum (P a)  = P (signum a)
   fromInteger n = P (fromInteger n)

instance Fractional Probability where
   P a / P b     = P (a / b)
   fromRational a = P (fromRational a)

instance Real Probability where
   toRational (P a) = toRational a

fromDouble :: Double -> Probability
fromDouble = P

display :: Int -> Rational -> String
display digits r
   | digits > 0  = show n1 ++ "." ++ leading (show n2)
   | digits == 0 = show n1
   | otherwise   = error "display: negative number of digits"
 where
   n, n1, n2 :: Integer
   n        = round (r * (10^digits))
   (n1, n2) = n `quotRem` (10^digits)

   leading :: String -> String
   leading s = replicate (digits - length s) '0' ++ s