
2014-02-15 14:42 GMT-05:00 James Toll
Hi,
I am trying to write a simple function to determine the divisors of an integer. In its simplest form the type signature should be something like:
divisors :: Int -> [Int] divisors x = 1 : lower ++ upper ++ x : [] where lower = filter (\y -> mod x y == 0) [2..(ceiling . sqrt) x] upper = sort $ map (div x) lower
Although, I think my type signature isn't complete as it ignores a lot of what's going on in the function. Regardless, the function throws an error when evaluated. I don't know if I just need a more accurate type signature, or if there is a bigger problem.
From what I can tell, my problem is in the lower function, but when I deconstruct it into its parts, they work individually and as a whole, but not as a stand-alone function. For example, using x = 36:
Prelude> [2..(ceiling . sqrt) 36] [2,3,4,5,6]
:t [2..(ceiling . sqrt) 36] [2..(ceiling . sqrt) 36] :: Integral t => [t]
Prelude> filter (\y -> mod 36 y == 0) it [2,3,4,6]
:t filter (\y -> mod 36 y == 0) filter (\y -> mod 36 y == 0) :: Integral a => [a] -> [a]
Or as a whole:
Prelude> filter (\y -> mod 36 y == 0) [2..(ceiling . sqrt) 36] [2,3,4,6]
:t filter (\y -> mod 36 y == 0) [2..(ceiling . sqrt) 36] filter (\y -> mod 36 y == 0) [2..(ceiling . sqrt) 36] :: Integral a => [a]
But when I define this as a function, it throws an error when evaluated.
Prelude> let lower x = filter (\y -> mod x y == 0) [2..(ceiling . sqrt) x]
:t lower lower :: (Floating b, Integral b, RealFrac b) => b -> [b] :t 36 36 :: Num a => a
Prelude> lower 36
Take a look to all the thing your function request, and what are you giving to it, the 36 satisfy those requirements? (Class constraints). furthermore, the Int type you are using satisfies that too? The most messy part is: (ceiling . sqrt) , that's the root of all the problem. Remember there is no implicit conversion between data types -- Alejandro Gómez Londoño