úÎ ,+  portablestablewren@community.haskell.org A LogFloat is just a   with a special interpretation.  The 3 function is presented instead of the constructor, 8 in order to ensure semantic conversion. At present the   H instance will convert back to the normal-domain, and so will underflow 8 at that point. This behavior may change in the future. FPerforming operations in the log-domain is cheap, prevents underflow, F and is otherwise very nice for dealing with miniscule probabilities. C However, crossing into and out of the log-domain is expensive and = should be avoided as much as possible. In particular, if you're ) doing a series of multiplications as in lp * logFloat q * logFloat  r it's faster to do lp * logFloat (q * r) if you're reasonably * sure the normal-domain multiplication won't underflow, because that ; way you enter the log-domain only once, instead of twice. #Even more particularly, you should avoid addition whenever possible.  Addition is provided because it'$s necessary at times and the proper E implementation is not immediately transparent. However, between two  LogFloat$s addition requires crossing the exp/log boundary twice;  with a LogFloat and a regular number it's three times since the I regular number needs to enter the log-domain first. This makes addition H incredibly slow. Again, if you can parenthesize to do plain operations  first, do it! Since the normal  " throws an error on zero, we have @ to redefine it in order for things to work right. Arguing from  limits it's obvious that log 0 == negativeInfinity. If you're using some   type that's not built in, verify  this equation holds for your 0 and negativeInfinity. If it  doesn''t, then you should avoid importing our  and will probably , want converters to handle the discrepency. ?The most generic numeric converter I can come up with. All the  built-in numeric types are  , though  and  aren't  . @Reduce the number of constant string literals we need to store. 9We need these guards in order to ensure some invariants. It'=s unfortunate that notANumber is not equal to itself, but we B can hack around that. Is there any efficiency difference between , these two tests? If not, then we could use log . guardNonNegative  fun = guardIsANumber fun . log& in order to remove guardNonNegative. @A constructor which does semantic conversion from normal-domain  to log-domain. EConstructor which assumes the argument is already in the log-domain. ?Return our log-domain value back into normal-domain. Beware of  overflow/ underflow. =Return the log-domain value itself without costly conversion           !logfloat-0.8.3Data.Number.LogFloatghc-prim GHC.Typesbase Text.ShowPreludeinteger GHC.IntegerLogFloatinfinitynegativeInfinity notANumberlog toFractionallogFloat logToLogFloat fromLogFloatlogFromLogFloatDoubleGHC.ShowShow GHC.FloatFloatingGHC.RealRealIntGHC.Integer.InternalsInteger FractionalerrorOutOfRangeguardNonNegativeguardIsANumber