jek
jek

Reputation: 563

max and min with NaN in Haskell

Why is it that the max of NaN and a number is NaN, but the min of NaN and a number is the number? This seems to be at odds with a few other languages I have tried:

In Haskell:

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

In Python

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

In JavaScript

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

Upvotes: 18

Views: 1470

Answers (3)

augustss
augustss

Reputation: 23014

The Haskell report specifies that (min x y, max x y) will return either (x, y) or (y, x). This is a nice property, but hard to reconcile with a symmetric treatment of NaN.

It's also worth mentioning that this is exactly the same asymmetry as the SSE2 instructions MINSD and MAXSD exhibit, i.e., Haskell min (for Double) can be implemented by MINSD and max by MAXSD.

Upvotes: 10

Potatoswatter
Potatoswatter

Reputation: 137940

I'm not a Haskell programmer, but it appears that the floating-point functions are called fmin and fmax. For whatever reason, the generic functions applied to floating-point types do not follow standard numeric behavior.

fmin and fmax comply with IEEE 754:2008 §5.3.1:

minNum(x, y) is the canonicalized number x if x < y, y if y < x, the canonicalized number if one operand is a number and the other a quiet NaN.

Note that this behavior is opposite JavaScript. Do not do as JavaScript does ;v) .

Upvotes: 7

Evan Sebastian
Evan Sebastian

Reputation: 1744

Not quite, min 1.0 (0/0) will return NaN, for instance.

This is because any comparison with NaN is defined to return false, and by the definiton of min and max below :

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

min and max with NaN will return second and first argument, respectively.

Upvotes: 8

Related Questions