I've been reading Learn You a Haskell for a few days (chaps 1-6) and there are several things, even in the land of newbies, which are not clear to me.
For instance, I've been trying to implement a script to solve this classic problem of finding the largest prime factor of an integer.
I'm pretty sure my approach,
- check if the number is a square and return its square root if so,
- otherwise search for divisors downward from its square root, scanning only odd numbers,
is probably not the right one, is plainly wrong, as pointed out in the answer and the comments (I hope I would have realized this myself, if I had been able to write a compilable code), but at least it's being a chance to practice Haskell's syntax and not only.
The only commented line is the one with which I'm having issue. What is "strange" to me, is that the errors are about the two lines just after that, whereas everything works fine if I change the lamda to something which does not use both x
and e
(except that the result is wrong, clearly).
largestprime x
| isSquare = srx
| otherwise = head $ filter (\e -> x `mod` e == 0) lst --Lambda
where intsqrt = floor . sqrt
isSquare = sqrt x == fromInteger(intsqrt x)
srx = intsqrt x
lst = [i,i-2..]
where i = if odd srx then srx else srx - 1
My understanding is that something is wrong with the types that are deduced for e
and x
, however the error is not very helpful, given my current level:
Main.hs:59:21: error:
• No instance for (RealFrac Integer) arising from a use of ‘floor’
• In the first argument of ‘(.)’, namely ‘floor’
In the expression: floor . sqrt
In an equation for ‘intsqrt’: intsqrt = floor . sqrt
|
59 | where intsqrt = floor . sqrt
| ^^^^^
Main.hs:59:29: error:
• No instance for (Floating Integer) arising from a use of ‘sqrt’
• In the second argument of ‘(.)’, namely ‘sqrt’
In the expression: floor . sqrt
In an equation for ‘intsqrt’: intsqrt = floor . sqrt
|
59 | where intsqrt = floor . sqrt
| ^^^^
Main.hs:60:22: error:
• No instance for (Floating Integer) arising from a use of ‘sqrt’
• In the first argument of ‘(==)’, namely ‘sqrt x’
In the expression: sqrt x == fromInteger (intsqrt x)
In an equation for ‘isSquare’:
isSquare = sqrt x == fromInteger (intsqrt x)
|
60 | isSquare = sqrt x == fromInteger(intsqrt x)
| ^^^^^^
Failed, no modules loaded.
Concerning e
, it is an element of lst
, which is a list whose elements are of the same type as srx
, which is the type in output from floor
, which based on :t floor
seems to be Integral
. So maybe I just have to define the type of largestprime
appropriately?
I've seen some questions exist already on the topic, like this one or this one. However I'm a bit confused at the moment.
Besides receiving help so that I can solve the problem, it'd be also nice to receive some advices on how to read those errors, which at the moment are close to arabic for me.