Это может быть случай целочисленного переполнения. Значение, передаваемое в fromIntegral
в вашем делителе, равно 3191195800, что больше, чем может вместить 32-разрядное знаковое Int.
В ghci (или что вы используете), используйте
:t sumTup
:t sumFixTup
чтобы увидеть типы этих переменных. Я предполагаю, что вы обнаружите, что sumTup
- это (Int, Int, Int, Int)
(переполнение), а sumFixTup
- это (Integer, Integer, Integer, Integer)
(не переполнение).
Редактировать: если подумать, кортеж Ints не может быть равен кортежу целых чисел. Тем не менее, я думаю, что ghci исправит тип sumFixTup
как кортеж целых чисел, тогда как sumTup
, вероятно, имеет тип вида (Num a) => (a, a, a, a)
или (Integral a) => (a, a, a, a)
, который зависит от функции, определяющей его. 1017 *
Затем Ghci преобразует их в целые числа для сравнения с sumFixTup
, но может преобразовывать их в целые числа при вычислении делителя в phi
, вызывая переполнение.
Другое редактирование: KennyTM, вы наполовину правы:
Prelude> :t (1,2,3,4)
(1,2,3,4) :: (Num t, Num t1, Num t2, Num t3) => (t, t1, t2, t3)
Prelude> let tup = (1,2,3,4)
Prelude> :t tup
tup :: (Integer, Integer, Integer, Integer)
Итак, для примеров, приведенных в вопросе:
putStrLn (show ((138, 136, 17, 204) == sumTup))
Литерал (138, 136, 17, 204)
выводится как кортеж Int
, чтобы соответствовать sumTup
, и они сравниваются равными.
putStrLn (show (phi sumTup))
sumTup
состоит из Int
с, вызывая переполнение, как указано выше.
putStrLn (show (phi sumFixTup))
sumFixTup
состоит из Integer
с, что дает правильный результат. Обратите внимание, что sumTup
и sumFixTup
никогда не сравнивались напрямую, поэтому мое более раннее редактирование было основано на неправильном прочтении.