Есть ли ошибка в минимальной функции?

У меня есть список mins 415920 номеров, все должны быть закрыты до 0.1:

Prelude Lib> take 5 mins
[9.83610706554002e-2,9.847021825032128e-2,9.847021825032128e-2,9.898395035483082e-2,9.898395035483082e-2]

Тем не мение:

Prelude Lib> minimum mins
0.10087849151477328

minimum функция не должна возвращать минимум?

Этот результат звучит правдоподобно:

Prelude Lib> foldr min 100000 mins
1.1763616593045858e-4

Это ошибка, или я неправильно понимаю minimum?

Аналогичная проблема с maximum:

Prelude Lib> maximum mins
3261145.0627630088
Prelude Lib> foldr max 0 mins
0.1207868227600914

Сортировка списка дает третий результат для максимума:

Prelude Lib> import Data.List as L
Prelude Lib L> mins' = sort mins
Prelude Lib L> head mins'
1.1763616593045858e-4
Prelude Lib L> last mins'
0.10295664278431726

И применение minimum и maximum в отсортированном списке дает третий результат для минимума:

Prelude Lib L> minimum mins'
0.10045801977483232
Prelude Lib L> maximum mins'
3261145.0627630088

редактировать

После комментария @max630 я искал в списке текстовый редактор. 3261145.0627630088 действительно здесь, и есть некоторые NaN:

NaN,NaN,3261145.0627630088

Вывод: похоже, что minimum дает неправильный результат, а maximum дает правильный результат.

foldr max дает неверный результат, foldl max дает хороший результат:

> foldl max 0 mins
3261145.0627630088

Ответы

Ответ 1

Причина всех проблем в том, что список содержит NaN. По-видимому, это нарушало требование общего заказа Ord [*], поэтому вы не можете ожидать, что алгоритмы, которые используют порядок - либо минимальный выбор, либо сортировку - для получения правильного результата, когда он находится на входе. Вместо этого они будут производить что-то, что зависит от их внутренней реализации, и могут быть разными в зависимости от кажущихся несущественными причин, например, порядка ввода. Вы должны отфильтровать его, прежде чем делать что-либо еще.

[*] У Ord нет законов, написанных явно (ни Eq которые NaN также не разрывает), а вот пример нарушения правила тотальности, как описано в Википедии (спасибо @sjakobi для исправления):

Prelude> let nan = 0 / 0
Prelude> nan
NaN
Prelude> nan <= 1
False
Prelude> 1 <= nan
False
Prelude>