Hi,
I'm working with some classes that handle probabilities in terms
of their log or log-odds. Such classes only handle non-negative
real numbers. For example, from Numeric.Log:
newtype Log a = Exp { ln :: a }
Since the log of a positive number can be negative, we don't want to use the same type to hold the number and its logarithm. Standard functions exp, log, and (**) are awkward because they all assume that numbers and their powers have the same type:
log,exp :: a -> a (**) :: a -> a -> a
In comparison the ln function from Numeric.Log has a different
signature that allows a number and its logarithm to have different
types:
ln :: Log a -> a Exp :: a -> Log a
In order to address this, I have tried defining a type class Pow:
class Fractional a => Pow a where pow :: a -> Double -> a ln :: a -> Double expTo :: Double -> a
Probably I should replace "Double" here by a type variable b, but
I have not done so yet. I'm mostly interested in abstracting over
the type of non-negative number, because I have another type Prob
that is designed to handle numbers like 1e - 100000, and 1.0 -
1e-100000.
data Prob = Zero | Odds Double | One | IOdds Double |
Infinity -- store probability in terms of log odds = log
(p/(1-p))
Q1. Does anybody know of an existing Haskell module that implements something like the Pow class above?
Also, it would be nice (notationally) if I could use log, exp,
and (**) instead of ln, expTo, and pow. In theory we could factor
out log, exp, (**), sqrt, and logBase from Floating into a new
superclass of Floating, so that Floating only contains trig and
hyper-trig functions.
But I suspect this will not work because the methods in class Pow
are more ambiguous. For example, if (x :: Double) then you can do
(expTo x :: Prob) and (expTo x :: Log Double) and they will yield
different types.
Q2. Does anybody have a suggestion for a nicer design?
Thanks!
-BenRI