The Validity instance of Double and Float have been the most frequently modified and most controversial part of the validity library. This post announces validity-0.9.0.0 and discusses the changes.

History

The following is a concise summary of the history of Validity Double for reference.

Version 0.1.0.0 until 0.3.0.0 had no Validity instance for Double

instance for Version 0.4.0.0 until 0.6.0.0 had an instance for Validity where -Infinity , +Infinity and NaN are not considered valid.

where , and are not considered valid. Version 0.7.0.0 had an instance for Validity where -Infinity , +Infinity , NaN and -0 are not considered valid.

where , , and are not considered valid. Version 0.8.0.0 had an instance for Validity where -Infinity , +Infinity and NaN are not considered valid.

where , and are not considered valid. Version 0.9.0.0 has an instance for Validity where any double is trivially valid.

Controversy

The Validity instance for Double has been highly controversial. The debate centers around whether NaN should be considered a valid value of type Double . The reason that this matters is because Eq Double exist and not such that == is an equivalence relationship. On a related note: Ord Double is similarly broken.

The reasons that led to the decision to consider NaN a valid value are saved in the repository as well, and can be found here.

The main trade-offs are as follows:

Consider NaN valid

This makes sense if you consider Double the implementation of the IEEE 754 Double precision floating point standard.

the implementation of the IEEE 754 Double precision floating point standard. Round-trip properties involving Double do not hold any more. Indeed, when encoding NaN and (correctly) decoding it to NaN again, the result will not equal the starting point because NaN == NaN evaluates to False .

do not hold any more. Indeed, when encoding and (correctly) decoding it to again, the result will not equal the starting point because evaluates to . Parsers can now be tested with producesValidsOnValids in the context of Double where they couldn't be otherwise. Indeed, decoding a NaN value could be correct.

in the context of where they couldn't be otherwise. Indeed, decoding a value could be correct. You can still consider a NaN invalid if it occurs as part of a custom type.

Consider NaN invalid

This makes sense if you consider Double as a type of rational numbers.

as a type of rational numbers. This makes sense if you see NaN as an unhandled error instead of a value.

as an unhandled error instead of a value. This hides broken code: Eq Double and Ord Double when testing for valid values, for better or for worse.

and when testing for valid values, for better or for worse. Would avoid boilerplate if one's own code does not deal with NaN values.

values. You can still use genUnchecked to test code with NaN values if you want.

Breakage