У double ломается ассоциативность, а равенство даже не рефлексивно
Точнее, чем «законов нет»:
| Закон | Держится? |
|---|---|
Коммутативность + и × | да |
| Ассоциативность | нет |
| Нейтральный элемент | почти: (−0) + 0 даёт +0, а не −0 |
| Дистрибутивность | нет |
| Равенство рефлексивно | нет: NaN ≠ NaN |
Последняя строка самая тяжёлая и объясняет остальные. Равенство на double — не отношение эквивалентности. А без рефлексивного равенства нельзя объявить категорию с равенством (сетоид).
Что из этого следует. Тип «число без NaN» был бы законным — отдельная небольшая работа с понятной пользой. И отдельно: nan-is-reachable изнутри языка, так что вычеркнуть его нельзя простым соглашением.
Практическое. Когда кто-то говорит «объявим у чисел моноид» — вот причина, по которой это не выйдет, и вот что надо поменять, чтобы вышло.
Связано: floating-point-bits-are-exact, nan-is-reachable, infinity-is-legal-without-subtraction