You can see the problem if you specify the type:
divisors :: (Integral t, Floating t) => t -> [(t, t)]
and then check what Integral and Floating :
Prelude> :info Floating class Fractional a => Floating a where instance Floating Float -- Defined in GHC.Float instance Floating Double -- Defined in GHC.Float
and
Prelude> :info Integral class (Real a, Enum a) => Integral a where instance Integral Integer -- Defined in GHC.Real instance Integral Int -- Defined in GHC.Real
therefore, it cannot be either Int, Integer, Float, or Double. You have problems...
Fortunately, we can convert between types, so while sqrt requires a floating point, and mod requires an integral (btw, rem faster), we can either, for example, do away with floating point division
divisors :: Integer -> [(Integer, Integer)] divisors x = [(a, x `div` a) | a <- [2..ceiling (sqrt (fromIntegral x))], x `rem` a == 0] > divisors 100 [(2,0),(4,0),(5,0),(10,0)]
However, you need to think a lot about what you really want to do when converting integer types to floating points, via sqrt ...
Don Stewart May 05 '11 at 3:58 a.m. 2011-05-05 03:58
source share