[Haskell-beginners] type error in sub-function

James Toll james at jtoll.com
Sat Feb 15 21:52:25 UTC 2014


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



More information about the Beginners mailing list