Давайте немного не запутаем это:
Prelude> (\x -> x `mod` (floor . sqrt) x) 2
<interactive>:1:24:
Ambiguous type variable `b' in the constraints:
`Floating b' arising from a use of `sqrt' at <interactive>:1:24-27
`Integral b' arising from a use of `mod' at <interactive>:1:7-30
`RealFrac b' arising from a use of `floor' at <interactive>:1:16-20
Probable fix: add a type signature that fixes these type variable(s)
Вы используете значение n
в качестве числа с плавающей точкой, передавая его sqrt
и floor
.Затем вы используете этот результат как int, передавая этот результат в mod
.Компилятор не может назвать тип со всеми этими экземплярами.
Причина, по которой он работает в вашем первом примере, другими словами
Prelude> 2 `mod` (floor . sqrt) 2
0
, заключается в том, что вы используете два разных числовых литерала,Один может быть int, а другой - float.Если вы используете одно и то же значение для обоих, вам нужно вызвать fromIntegral
для преобразования int в число с плавающей точкой.
Вы можете получить другое сообщение об ошибке, добавив сигнатуру типа, изменив [2..]
на[2..] :: [Integer]
:
No instance for (RealFrac Integer)
arising from a use of `floor' at <interactive>:1:52-64
No instance for (Floating Integer)
arising from a use of `sqrt' at <interactive>:1:58-63
Это может сделать более понятным, что вы используете значение n
в качестве двух разных типов.