úÎ P~O     portablestablewren@community.haskell.orgMany numbers are not   yet, even though they can > represent arbitrarily large values, they are not necessarily ? able to represent transfinite values such as infinity itself. @ This class is for types which are capable of representing such = values. Notably, this class does not require the type to be   nor & since integral types could also have ) representations for transfinite values. &In particular, this class extends the  projection to have  a maximum value  and a minimum value , ! as well as an exceptional value . All the natural  laws regarding infinity and negativeInfinity should pertain.  Additionally, infinity - infinity should return  notANumber  (as should 0/0 and infinity/infinity if the type is   Fractional). Any operations on  notANumber will also return   notANumber-, and any equality or ordering comparison on   notANumber must return False. Minimum complete definition is infinity,  isInfinite, and  isNaN. =A transfinite value which is greater than all finite values. : Adding or subtracting any finite value is a no-op. As is 7 multiplying by any non-zero positive value (including  infinity3), and dividing by any positive finite value. Also  obeys the law "negate infinity = negativeInfinity with all  appropriate ramifications. :A transfinite value which is less than all finite values.  Obeys all the same laws as infinity with the appropriate " changes for the sign difference. <An exceptional transfinite value for dealing with undefined < results when manipulating infinite values. Since NaN shall > return false for all ordering and equality operations, there 5 may be more than one machine representation of this value. Return true for both infinity and negativeInfinity,  false for all other values. Return true only for  notANumber. 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 we can see that log 0 == negativeInfinity. %In order to improve portability, the  class is required  to indicate that the ) type does in fact have a representation $ for negative infinity. Both native Floating types ( and  4) are supported. If you define your own instance of   Transfinite+, verify the above equation holds for your 0 and  negativeInfinity . If it doesn'#t, then you should avoid importing  our log= and will probably want converters to handle the discrepancy  when dealing with LogFloats. ?The most generic numeric converter I can come up with. All the  built-in numeric types are  , though  and   aren't  1. Beware that converting transfinite values into Ratio 8 types is error-prone and non-portable, as discussed in  Data.Number.Transfinite. @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.4Data.Number.TransfiniteData.Number.LogFloatbasePreludeData.Ordghc-prim GHC.Types Text.Showinteger GHC.Integer TransfiniteinfinitynegativeInfinity notANumber isInfiniteisNaNLogFloatlog toFractionallogFloat logToLogFloat fromLogFloatlogFromLogFloatGHC.EnumBoundedGHC.Real Fractional GHC.FloatFloating GHC.ClassesOrdDoubleGHC.ShowShowFloatRealIntGHC.Integer.InternalsIntegererrorOutOfRangeguardNonNegativeguardIsANumber