Подтвердить что ты не робот

Max и min с NaN в Haskell

Почему макс NaN и число NaN, но min NaN и число - это число? Это, похоже, противоречит нескольким другим языкам, которые я пробовал:

В Haskell:

max (0/0) 1 -- NaN
min (0/0) 1 -- 1.0

В Python

>>> max(float("nan"),1) #nan
>>> min(float("nan"),1) #nan

В JavaScript

> Math.max(0/0,1) //NaN
> Math.min(0/0,1) //NaN
4b9b3361

Ответ 1

В отчете Haskell указано, что (min x y, max x y) вернет либо (x, y), либо (y, x). Это приятное свойство, но трудно примириться с симметричной обработкой NaN.

Также стоит упомянуть, что это точно та же асимметрия, что и команды SSE2 MINSD и MAXSD, т.е. Haskell min (для Double) может быть реализована с помощью MINSD и max на MAXSD.

Ответ 2

Не совсем, min 1.0 (0/0) вернет NaN, например.

Это связано с тем, что любое сравнение с NaN определяется как возвращаемое значение false, а по определению min и max ниже:

max x y 
     | x <= y    =  y
     | otherwise =  x
min x y
     | x <= y    =  x
     | otherwise =  y

min и max с NaN вернут второй и первый аргументы соответственно.

Ответ 3

Я не программист Haskell, но кажется, что функции с плавающей запятой называются fmin и fmax. По какой-то причине общие функции, применяемые к типам с плавающей запятой, не соответствуют стандартным числовым поведением.

fmin и fmax соответствуют требованиям IEEE 754: 2008 §5.3.1:

minNum (x, y) является каноническим числом x, если x < y, y, если y < x, каноническое число, если один операнд является числом, а другой - тихим NaN.

Обратите внимание, что это поведение противоположно JavaScript. Не делайте так, как это делает JavaScript: v).