I’m learning Haskell and I’m trying to write a function to return a list of factors for a number. Here’s what I have:
factors :: Int -> [Int]
factors n = [x | x <- [2..s], n `mod` x == 0]
where s = floor (sqrt n)
When I try to load the module in ghci, I get two errors,
p003.hs:3:14:
No instance for (RealFrac Int)
arising from a use of `floor' at p003.hs:3:14-27
Possible fix: add an instance declaration for (RealFrac Int)
In the expression: floor (sqrt n)
In the definition of `s': s = floor (sqrt n)
In the definition of `factors':
factors n = [x | x <- [2 .. s], n `mod` x == 0]
where
s = floor (sqrt n)
p003.hs:3:21:
No instance for (Floating Int)
arising from a use of `sqrt' at p003.hs:3:21-26
Possible fix: add an instance declaration for (Floating Int)
In the first argument of `floor', namely `(sqrt n)'
In the expression: floor (sqrt n)
In the definition of `s': s = floor (sqrt n)
Failed, modules loaded: none.
Any suggestions?
The parameter has type
Int, so you cannot calculate a square root for it. You need to convert it to a floating point type first, which you can do with fromIntegral. Unlike some other languages, Haskell does not automatically promote integers to floating point numbers (nor do any other automatic type conversions).So change
sqrt ntosqrt (fromIntegral n).