How do I distinguish negative zero with Aeson? - haskell

Haskell distinguishes negative zero:
ghci> (isNegativeZero (0 :: Float), isNegativeZero (-0 :: Float))
(False,True)
JSON also allows for distinguishing them, since both "0" and "-0" are valid, syntactically.
But Aeson throws away the sign bit:
ghci> isNegativeZero <$> eitherDecode "-0"
Right False
Why? How can I decode a JSON document while distinguishing non-negative and negative zero?

It looks like in Data.Aeson the floating point number is constructed using Data.Scientific.scientific
scientific :: Integer -> Int -> Scientific
scientific c e constructs a scientific number which corresponds to the Fractional number: fromInteger c * 10 ^^ e.
Since the mantissa is an Integer, where we have 0 == -0, it can not construct a negative zero. Not the best API for constructing special floating point values, it seems.
Perhaps you should file a bug for aeson, asking for a workaround in the parser.

Related

How to negate every number on a list except a specific number? Haskell

I'm relatively new to haskell, and know that we can use the negation to negate a list. The negation does not negate the number zero in a regular list of type float, int, and integer. But what if you had a list of a different data type? If I negate a different data type, then the number zero in that list will also be negated. Is there a way to not negate numbers like 0 and 0.0 in the list?
You say
The negation does not negate the number zero in a regular list of type float
but this assertion is incorrect. See:
> negate 0 :: Float
-0.0
> negate 0 :: Double
-0.0
> map negate [0] :: [Float]
[-0.0]
The behavior of the rest of your code follows directly from this fact. For further reading I highly recommend What Every Computer Scientist Should Know About Floating-Point Arithmetic, which includes an in-depth discussion of why floating point must have a negative zero distinct from zero. But the short version is this sentence from page 201:
If zero did not have a sign, then the relation (1/(1/x)) = x would fail to hold when x = ±∞.

Why does "take" change datatype in haskell?

I'm writing a function which takes elements from a list and returns them.
Pretty simple I thought. But when using "take" in for example: take 2 [1.2,3,4]
it returns: [1.2,3.0] when I actually want [1.2, 3]
I thought for creating a function that goes through the list and cuts unnecessary decimals but I can't get my head around it seeing haskell doesn't accept my comparison with x & round(x) in
function :: [a] -> [a]
function(x:xs)
if x == round(x) = round(x):function xs
else x:function xs
So A: Are there any simpler solutions?
B: Why can't haskell compare x with round(x)?
You say, "I actually want [1.2, 3] [and not [1.2, 3.0]]". I interpret this to mean that you want a list that contains Floats or the like for fractional numbers and Ints or the like for numbers without a fraction part.
You can't have this.
All lists in Haskell are homogeneous: every element has the same type.
There are some things you can do; for example, you can have tagged unions, the canonical example being Either. So
[Left 1.2, Right 3] :: [Either Double Integer]
would be fine; but you need to explicitly tag each element.
This is also more or less the answer to why x == round x doesn't work: the (==) operator takes two arguments of the same type; whereas typically round cannot return a value of the same type as its argument. You might like properFraction instead:
> properFraction 3
(3,0.0)
> properFraction 1.2
(1,0.19999999999999996)
You can check the second part of this to determine whether your number is a whole number or not (and when it is, the first part will be the result of round).
take does not change the type of list elements. Start up GHCi and follow along. My prompt is >>>.
>>> :t [1.2,3,4]
[1.2,3,4] :: Fractional t => [t]
This says the list elements have some Fractional type.
>>> :t [1.2,3.0,4.0]
[1.2,3.0,4.0] :: Fractional t => [t]
GHCi says the same thing here as well. What is going on?
>>> :t 2
2 :: Num t => t
>>> :t 2.0
2.0 :: Fractional t => t
A number literal without a decimal is inferred to have some Num type. A number literal with a decimal is inferred to have some Fractional type. For two elements to be in the same list, they must have the same type. What is the common type for 2 and 2.0?
>>> :t 2 `asTypeOf` 2.0
2 `asTypeOf` 2.0 :: Fractional a => a
All Fractional types are Num types, and so the common type for 2 and 2.0 is some Fractional type.
>>> [1.2,3,4]
[1.2,3.0,4.0]
We can see from the printing of the list that all the elements have been inferred as a Fractional type. This defaults to Double.
To remove unnecessary decimals from a list you will have to be more specific about what type you want this list to have. A list of Int has no decimals and a list of Double always has decimals. A single list cannot have both Int and Double typed elements.

What's the difference between the classes Floating and Fractional in Haskell?

What is the difference is between the Floating and Fractional classes in Haskell?
Very roughly:
Fractional is the class of types that can represent (exactly or at least in a decent approximation) any rational number. It may ad lib also be able to represent other numbers, but that's not important.In other terms, it's just the class of number types that have a division operation; since it's a subclass of Num it follows from this that the types must contain the rational numbers.
Floating is the class of number types that are closed under limits in the Cauchy sense, i.e. complete spaces. This is necessary to do any sort of calculus. The methods of the Floating class are functions that are mathematically defined as limits, namely infinite sums (which are the limits of the sequence of partial sums of taylor series).Since you can define the real numbers as limits of sequences of rational numbers and because again Floating is a subclass of Fractional, any Floating type is able to represent (again, at least to a decent approximation) any real number.
A good way to visualise the difference is through topology: Floating types are connected spaces, i.e. they form a continuum. What this means for floating point numbers is: every value is understood as a whole interval of real numbers (because floating-point always has some uncertainty). When you lay these intervals side by side, you tile the entire real numbers (at least to ±10300) without gaps.
By contrast, some Fractional types are not connected. In particular, Rational can exactly represent all its (rational-number) values, so each value is just an “infinitely small point”. You can never cover the entire real line with such points, and you can not compute functions like sin or log since the result of these functions is usually a non-rational real number.
It's worth pondering a bit what this “decent approximation” means. The Haskell standard doesn't define this. This story about every floating point number representing a whole interval of real numbers captures it quite well IMO. More generally, we might say: Num/Fractional/Floating are the classes of types that represent equivalance classes of integer/rational/real numbers. In fact, these classes need not even be “small” intervals: in particular the finite types like Word32 or the standard Int can be understood in a modular arithmetic sense, manifesting in results like (2^70 :: Int) == 0, i.e. the equivalence classes are then numbers spaces by a multiple of 264.
In cases like Integer or Rational, the equivalence classes actually contain only a single element, i.e. the numbers are represented exactly. For real numbers, this is actually also possible, but much more tricky, it's called exact real arithmetic. There are libraries such as aern that do this.
The definitions of Fractional and Floating can be found in the documentation of the Prelude:
class Num a => Fractional a where
(/) :: a -> a -> a
recip :: a -> a
fromRational :: Rational -> a
Fractional numbers, supporting real division.
[...]
class Fractional a => Floating a where
pi :: a
exp :: a -> a
log :: a -> a
sqrt :: a -> a
(**) :: a -> a -> a
logBase :: a -> a -> a
sin :: a -> a
cos :: a -> a
tan :: a -> a
asin :: a -> a
acos :: a -> a
atan :: a -> a
sinh :: a -> a
cosh :: a -> a
tanh :: a -> a
asinh :: a -> a
acosh :: a -> a
atanh :: a -> a
Trigonometric and hyperbolic functions and related functions.
[...]
So to translate that into English: A Fractional is any kind of number for which I can define a division:
(/) :: Fractional a => a -> a -> a
That can for instance be the case for floating point numbers, but also for fractions (where a fraction has a numerator and denominator). This is not the case for Int because if dividing an Int by an Int does not always produce an Int (well technically floating point division on a computer is not exact, but that is another story).
A subset of Fractional numbers are Floating numbers where trigonometric are defined. It is for instance impossible that the sin of a fraction always produces a fraction: a sin is defined as an sum over an infinite sequence. Only for a very limited number of cases (like sin 0) it holds. Basically the only numbers on a computer for which trigonometric are defined (approximatively) are floating point numbers.

Type conversion and equality behaviour

I'm new to Haskell, and just stumbled across this problem. I'm trying to figure out an explaination, but I don't have enough experience with Haskell types to be sure.
The function:
mystery :: Int -> Int -> Float -> Bool
mystery x y z = not ((x==y) && ((fromIntegral y) == z ))
behaves as it seems like it would. It's basically checking if the values are all NOT equal, but doing a type conversion from an Integral y to make sure it can be compared with z
If this is true, then why does:
case1 = do
if mystery 1 1 1.00000001 -- a very small number
then putStrLn "True"
else putStrLn "False"
Print False (ie. The values are all equal, so 1 == 1 == 1.00000001) whereas:
case2 = do
if mystery 1 1 1.0000001 -- a larger number
then putStrLn "True"
else putStrLn "False"
Prints True? (ie. The values are not all equal)
I know it likely has something to do with precision, but I don't get it. Any help is greatly appreciated.
Floating point operations are generally approximate, and == is not one of the exceptions to that rule. Single-precision floating point (Float) runs out of precision pretty quickly, while the more-generally-useful double-precision floating point (Double) has some more. In either case, your decimal fraction will be converted approximately to binary floating point, and then the equality test will also be approximate. General rule: floating point representations are not numbers, and they are not even legitimate instances of the Eq class. If you want to use them, you need to pay attention to their limitations.
In this case, you need to think about when you want to consider the integer equal to the floating point representation. You may or may not want to rely directly on the built-in comparison and rounding operations.
For some of the details you'll have to think about, check out the classic What Every Computer Scientist Should Know About Floating-Point Arithmetic, and don't skip the corrections and updates in the footnotes.
Your code can be simplified to:
> (1.00000001 :: Float) == 1
True
Looks like Float simply doesn't have enough precision to store the last bits of 1.00000001, so it gets truncated to plain 1.
1/10^n can't be represented in base2 floating point (IEEE 754), so the value is probably truncated.
Semantically, for integer comparison it's probably more accurate to truncate the floating point value.
mystery :: Int -> Int -> Float -> Bool
mystery x y z = not (x == y && y == truncate z)

Floating point numbers, precision, and Parsec

Consider the following code:
import Text.Parsec
import Text.Parsec.Language
import Text.Parsec.String
import qualified Text.Parsec.Token as Token
float :: Parser Double
float = Token.float (Token.makeTokenParser emptyDef)
myTest :: String -> Either ParseError Double
myTest = parse float ""
Now, thanks to QuickCheck I know a magic number (I have aligned result for
convenience):
λ> myTest "4.23808622486133"
Right 4.2380862248613305
Some floating point numbers cannot be exactly represented in memory, some
operations easily introduce «fluctuations» into floating point numbers. We
all know that. However, cause of this parsing problem seems to be different.
A few words about tests that helped me discover this… feature. Put simply,
in these tests floating point value is generated, printed, and parsed back
(with Parsec). For example, number 9.2 is known to be impossible to
represent as floating
point value,
however it passes the tests (obviously because of «smart» printing
function). Why does 4.23808622486133 fail?
For those who believe that these numbers are the same and 4.23808622486133 is just shortest unambiguous representation of 4.2380862248613305:
a1 :: Double
a1 = 9.2000000000000003
a2 :: Double
a2 = 9.200000000000001
b1 :: Double
b1 = 4.23808622486133
b2 :: Double
b2 = 4.2380862248613305
Now:
λ> a1 == a2
True
λ> b1 == b2
False
Parsec does the conversion to Double using what amounts to
foldr (\d acc -> read [d] + acc / 10) 0 "423808622486133" :: Double
and as you point out, this is not equal to
423808622486133 / 100000000000000 :: Double
I agree that this should be considered a bug in Parsec.
This is still not fixed in Parsec. If this exact problem breaks your day, take a look at Megaparsec, which is a fork of Parsec that fixes many bugs and conceptual flaws, improves quality of error messages and more.
As you can see this problem is fixed there:
λ> parseTest float "4.23808622486133"
4.23808622486133
λ> parseTest float "4.2380862248613305"
4.2380862248613305
Disclosure: I'm one of the authors of Megaparsec.

Resources