
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] Prelude> filter (\y -> mod 36 y == 0) it [2,3,4,6] Or as a whole: Prelude> filter (\y -> mod 36 y == 0) [2..(ceiling . sqrt) 36] [2,3,4,6] 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] Prelude> lower 36 <interactive>:6:1: No instance for (RealFrac b0) arising from a use of `lower' The type variable `b0' is ambiguous Possible fix: add a type signature that fixes these type variable(s) Note: there are several potential instances: instance RealFrac Double -- Defined in `GHC.Float' instance RealFrac Float -- Defined in `GHC.Float' instance Integral a => RealFrac (GHC.Real.Ratio a) -- Defined in `GHC.Real' In the expression: lower 36 In an equation for `it': it = lower 36 <interactive>:6:7: No instance for (Num b0) arising from the literal `36' The type variable `b0' is ambiguous Possible fix: add a type signature that fixes these type variable(s) Note: there are several potential instances: instance Num Double -- Defined in `GHC.Float' instance Num Float -- Defined in `GHC.Float' instance Integral a => Num (GHC.Real.Ratio a) -- Defined in `GHC.Real' ...plus three others In the first argument of `lower', namely `36' In the expression: lower 36 In an equation for `it': it = lower 36 At this point, I’m not sure what I need to do to get his working properly. It appears to be a type error, but I’m apparently not understanding the error message enough to fix the problem. Any suggestions would be appreciated. Thanks, James

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

Hi, Alejandro Gomez already posted an answer that should be enough for you to figure out the solution by yourself, but I decided to post mine anyway, in case you have trouble understanding how to proceed. On Sat, Feb 15, 2014 at 01:42:15PM -0600, James Toll wrote:
Prelude> let lower x = filter (\y -> mod x y == 0) [2..(ceiling . sqrt) x] Prelude> lower 36
<interactive>:6:1: No instance for (RealFrac b0) arising from a use of `lower' The type variable `b0' is ambiguous Possible fix: add a type signature that fixes these type variable(s) Note: there are several potential instances: instance RealFrac Double -- Defined in `GHC.Float' instance RealFrac Float -- Defined in `GHC.Float' instance Integral a => RealFrac (GHC.Real.Ratio a) -- Defined in `GHC.Real' In the expression: lower 36 In an equation for `it': it = lower 36
<interactive>:6:7: No instance for (Num b0) arising from the literal `36' The type variable `b0' is ambiguous Possible fix: add a type signature that fixes these type variable(s) Note: there are several potential instances: instance Num Double -- Defined in `GHC.Float' instance Num Float -- Defined in `GHC.Float' instance Integral a => Num (GHC.Real.Ratio a) -- Defined in `GHC.Real' ...plus three others In the first argument of `lower', namely `36' In the expression: lower 36 In an equation for `it': it = lower 36
At this point, I’m not sure what I need to do to get his working properly. It appears to be a type error, but I’m apparently not understanding the error message enough to fix the problem. Any suggestions would be appreciated.
Your first instinct should be to look at the type signature of the function you just wrote, so you can figure out what `b0` means: λ: :t lower lower :: (Floating b, Integral b, RealFrac b) => b -> [b] See? It expects to be given something that belongs to Floating, Integral and RealFrac typeclasses. The Haskell Report contains a nice image of the dependencies between typeclasses along with the actual types that instantiate them[1] From looking at it, you can deduce that there is no type that belongs to all three typeclasses. Thus the type error. 1. https://www.haskell.org/onlinereport/classes.gif To fix this, let's take a step back and deconstruct your function to see where each of the constraints (the thing in the parentheses that goes before the type) comes from. It all starts with `sqrt`, which has the following type: λ: :t sqrt sqrt :: Floating a => a -> a By looking at the aforementioned diagram again, you can conclude that `a` here is either Float or Double. Next, you compose `sqrt` with `ceiling`, which has the following type: λ: :t ceiling ceiling :: (Integral b, RealFrac a) => a -> b Here, `a` can be Float or Double, and `b` is either Int or Integer. After the composition you have a function with the following type: λ: :t (ceiling . sqrt) (ceiling . sqrt) :: (Floating b, Integral c, RealFrac b) => b -> c It accepts Float or Double (which both belong to Floating and RealFrac typeclasses) and returns Int or Integer. But you want to feed it an Int! Unlike many other languages, Haskell never casts (converts) types unless you order to do so. So you need some function to convert an instance of Integral typeclass (Int or Integer) into instance of both Floating and RealFrac, i.e. a function with the following type: (Integral a, Floating b, RealFrac b) => a -> b For that, we have Hoogle[2] Type in the signature, hit Search and you will be presented with a list of matching functions. `fromIntegral`, which is the second result I've been given, is *exactly* what you need. Let's use it, rewriting `lower` as λ: let lower x = filter (\y -> mod x y == 0) [2..(ceiling . sqrt) (fromIntegral x)] λ: :t lower lower :: Integral a => a -> [a] 2. https://www.haskell.org/hoogle/ As you can see, you've got a function that accepts any instance of Integral typeclass, i.e. Int and Integer types. Precisely what was required. Hope that makes sense. -- Regards, Alexander Batischev

On Feb 15, 2014, at 2:38 PM, Alexander Batischev wrote:
Hi,
Alejandro Gomez already posted an answer that should be enough for you to figure out the solution by yourself, but I decided to post mine anyway, in case you have trouble understanding how to proceed.
Yes, thank you. I really appreciate both of you taking the time to respond to my question, but that’s exactly the problem I was having. I had broken down and inspected the type signature of the subsections of my “lower” function. Each subsection on its own seemed fine, but what was confusing me was the type signature for the whole thing. And I wasn’t sure how to fix it. I really appreciate you walking me through the process. Beforehand, I kind of guessed that I probably needed to use fromIntegral somewhere, but I wasn’t sure where, and even if I got lucky and guessed, I don’t think I would have understood why.
After the composition you have a function with the following type:
λ: :t (ceiling . sqrt) (ceiling . sqrt) :: (Floating b, Integral c, RealFrac b) => b -> c
It accepts Float or Double (which both belong to Floating and RealFrac typeclasses) and returns Int or Integer.
But you want to feed it an Int! Unlike many other languages, Haskell never casts (converts) types unless you order to do so.
Again, thank you for this very helpful explanation of the problem, and I understand that Haskell doesn’t cast types automatically. In fact I was relying on that as I built up my function. What I guess really confused me was that this worked: Prelude> filter (\y -> mod 36 y == 0) [2..(ceiling . sqrt) 36] [2,3,4,6] while this didn’t. Prelude> let lower x = filter (\y -> mod x y == 0) [2..(ceiling . sqrt) x] Prelude> lower 36 Since the former worked, I really expected the latter to work as well.
:t 36 36 :: Num a => a
I am still slightly confused about the type that I passed into the function. If the type of 36 is Numeric, that doesn’t seem to necessarily tell me that it is an Int. Float and Double are listed under Numeric in the chart (https://www.haskell.org/onlinereport/classes.gif). This seems like a really stupid question, but how do I know that I can’t pass a Numeric into a function like sqrt that is expecting a Float? ghci> :t sqrt sqrt :: Floating a => a -> a And again, why does it work in the former case when it’s not a function, but not in the latter as a function? If there is no casting going on, it seems like it should fail every single time. Why does it work at all?
As you can see, you've got a function that accepts any instance of Integral typeclass, i.e. Int and Integer types. Precisely what was required.
Hope that makes sense.
Yes, thank you. I do think I have a better understanding now. Best regards, James

On Sat, Feb 15, 2014 at 03:52:25PM -0600, James Toll wrote:
Again, thank you for this very helpful explanation of the problem, and I understand that Haskell doesn’t cast types automatically. In fact I was relying on that as I built up my function. What I guess really confused me was that this worked:
Prelude> filter (\y -> mod 36 y == 0) [2..(ceiling . sqrt) 36] [2,3,4,6]
while this didn’t.
Prelude> let lower x = filter (\y -> mod x y == 0) [2..(ceiling . sqrt) x] Prelude> lower 36
This is sneaky: in the first example, there are two occurrences of the number 36, and they have different types! Number literals are polymorphic, that is, they can be any type which is an instance of the Num class. The first 36 has type Integer, since it's constrained by 'mod' to be an instance of Integral, and GHC will pick the Integer type by default. The second 36, on the other hand, has type Double, since sqrt requires a type which is an instance of Floating. When you abstract this out into the function 'lower', however, the argument x can only have one type, i.e. the two occurrences of x are required to be the *same* type.
Since the former worked, I really expected the latter to work as well.
:t 36 36 :: Num a => a
I am still slightly confused about the type that I passed into the function. If the type of 36 is Numeric, that doesn’t seem to necessarily tell me that it is an Int. Float and Double are listed under Numeric in the chart (https://www.haskell.org/onlinereport/classes.gif). This seems like a really stupid question, but how do I know that I can’t pass a Numeric into a function like sqrt that is expecting a Float?
Note that Num (Numeric) is not a type, it is a type class. It does not make sense to say "the type of 36 is Numeric". A better way to say it is that "36 can have any type, as long as it is an instance of the Num type class". You *can* pass 36 into a function like sqrt, since anything which is an instance of Floating is required to also be an instance of Num. -Brent

Hi, On Sat, Feb 15, 2014 at 03:52:25PM -0600, James Toll wrote:
What I guess really confused me was that this worked:
Prelude> filter (\y -> mod 36 y == 0) [2..(ceiling . sqrt) 36] [2,3,4,6]
while this didn’t.
Prelude> let lower x = filter (\y -> mod x y == 0) [2..(ceiling . sqrt) x] Prelude> lower 36
Since the former worked, I really expected the latter to work as well.
Because in the first case, you have 36 in two places, and they have different types. In the second case, though, both numbers are replaced by `x`, that has one type. Something should have just clicked in your brain, and every piece fell in place, but if not, read on. In my previous email, I showed you what constraints a composition of ceiling and sqrt places on `x`: λ: :t (ceiling . sqrt) (ceiling . sqrt) :: (Floating b, Integral c, RealFrac b) => b -> c From here, you can see that `x` is only constrained by typeclasses Floating and RealFrac. But `lower` has one more constraint, Integral: λ: :t lower lower :: (Floating b, Integral b, RealFrac b) => b -> [b] Why is that? Because you do `mod`: λ: :t mod mod :: Integral a => a -> a -> a When you filter the list, `x` gets constrained by the Integral typeclass, which leads to the situation you observe - too many constraints, typechecker can't pick a type to satisfy them all. And what do we do? We help the compiler using `fromIntegral`, thus removing the Floating and RealFrac constraints from `x` (they're now placed on a result of `fromIntegral`).
:t 36 36 :: Num a => a
I am still slightly confused about the type that I passed into the function. If the type of 36 is Numeric, that doesn’t seem to necessarily tell me that it is an Int. Float and Double are listed under Numeric in the chart (https://www.haskell.org/onlinereport/classes.gif).
It's incorrect to say that "the type of 36 is Numeric", but I guess it's just bad wording - you get the idea right, 36 isn't necessary Int. There's a thing called "type defaulting". It's a set of rules that GHC follows in order to pick a type for a thing whose type is not specified, like 36. (Note that GHCi has slightly different, more relaxed rules.) So when you run `filter`, GHCi has to pick some type for the results, and it settles for Integer. But type defaulting doesn't kick in until the very last moment. Up until binding the result, it stays as polimorphic as possible: λ: :t 36 36 :: Num a => a The moment you bind the result, though, it gets concrete type: λ: let x = 36 λ: :t x x :: Integer
This seems like a really stupid question, but how do I know that I can’t pass a Numeric into a function like sqrt that is expecting a Float?
ghci> :t sqrt sqrt :: Floating a => a -> a
I don't know how well you understand typeclasses, so pardon me if I explain something you already know. The thing is, each typeclass adds some new restrictions (functions to implement) that narrow the choice of possible instances of that typeclass. Almost every type instantiates Eq, but only four standard ones instantiate Num. Furthermore, only two standard types instantiate Floating. That's why you can't pass every Num instance into sqrt - not every one of them implements all the necessary methods. Is that clear enough? -- Regards, Alexander Batischev PGP key 356961A20C8BFD03 Fingerprint: CE6C 4307 9348 58E3 FD94 A00F 3569 61A2 0C8B FD03

On Sun, Feb 16, 2014 at 12:53:42AM +0200, Alexander Batischev wrote:
But type defaulting doesn't kick in until the very last moment. Up until binding the result, it stays as polimorphic as possible:
λ: :t 36 36 :: Num a => a
The moment you bind the result, though, it gets concrete type:
λ: let x = 36 λ: :t x x :: Integer
It has nothing to do with binding, actually. The above is just due to the monomorphism restriction. If you turn it off (highly recommended!):
:set -XNoMonomorphismRestriction let x = 36 :t x Num a => a
-Brent

On Sat, Feb 15, 2014 at 06:00:14PM -0500, Brent Yorgey wrote:
It has nothing to do with binding, actually. The above is just due to the monomorphism restriction. If you turn it off (highly recommended!):
I stand corrected. Been thinking about it, actually, but somehow managed to miss it when tried things out in GHCi. Thanks! -- Regards, Alexander Batischev

On Feb 15, 2014, at 4:53 PM, Alexander Batischev
Something should have just clicked in your brain, and every piece fell in place, but if not, read on.
Yes, the light bulb has gone on. Thanks to you and Brent. I really appreciate both of your explanations to my follow-up question. It’s almost a bit difficult to keep up with responding while reading your excellent and very helpful responses. I do think I now understand what was going on in this particular instance and why I was tricking myself. It always seems so simple in hindsight. I’m sure this won’t be the last time I get tripped up on this though. But I’m hopeful I can better reason it out going forward. Thanks again for all the extremely helpful responses. Best, James

On Sat, Feb 15, 2014 at 05:11:39PM -0600, James Toll wrote:
On Feb 15, 2014, at 4:53 PM, Alexander Batischev
wrote: Something should have just clicked in your brain, and every piece fell in place, but if not, read on.
Yes, the light bulb has gone on. Thanks to you and Brent. I really appreciate both of your explanations to my follow-up question. It’s almost a bit difficult to keep up with responding while reading your excellent and very helpful responses. I do think I now understand what was going on in this particular instance and why I was tricking myself. It always seems so simple in hindsight. I’m sure this won’t be the last time I get tripped up on this though. But I’m hopeful I can better reason it out going forward.
Thanks again for all the extremely helpful responses.
Glad to be of help! For what it's worth, the whole numeric-types-and-type-classes thing is definitely one of the trickiest corners of Haskell, at least when starting out. I remember spending a good deal of time struggling through it at first too. -Brent

write a simple function to determine the divisors of an integer.
straight simple first, let { divides n x = (mod n) x == 0 ; divisors n = filter (divides n) [1..n] } in map divisors [255,256,257]
divisors x = 1 : lower ++ upper ++ x : [] where lower = filter (\y -> mod x y == 0) [2..(ceiling . sqrt) x] upper = sort $ map (div x) lower
time-critical millions: let { divides n x = (mod n) x == 0; divisors n = let { firsthalf = filter (divides n) [ 1 .. ceiling$sqrt$fromInteger n ] } in nub ( firsthalf ++ map (div n) (reverse firsthalf) ) } in divisors 256
participants (5)
-
Alejandro Gomez
-
Alexander Batischev
-
Brent Yorgey
-
James Toll
-
roman@czyborra.com