Reputation: 13908
I want to check if an Integral
is a square:
isSquare :: Integral n => n -> Bool
isSquare n = (>1) $ length (filter (\x -> n / x == x) numList)
where numList = reverse [1..n]
Apart from whether or not iterating through a list is the right approach here, when I try to compile this function I get the error:
No instance for (Fractional Int) arising from a use of ‘/’
My understanding of this is that since I am binding n
to the Integral
type, by dividing it I am breaking the function's rigid type construction. How can I fix my function so that it compiles?
Upvotes: 2
Views: 105
Reputation: 225074
You could add fromIntegral
to everything to get Fractional
s:
filter (\x -> fromIntegral n / fromIntegral x == fromIntegral x) numList
Or just square the number instead:
filter (\x -> n == x ^ 2)
Also, your length check shouldn’t be >1
. ==1
would make more sense, but you should use null
to avoid having to try every number every time (besides using a faster algorithm in the first place).
isSquare :: Integral a => a -> Bool
isSquare n = not $ null $ filter (\x -> n == x ^ 2) numList
where numList = [n,n-1..1]
Upvotes: 4