I am attempting to create a list of pythagorean triplets, that is, a list of tuples that each contain (x, y, z) such that x^2 + y^2 = z^2 and x, y, z are in range [1..n].
I've run into what seems to be a type error inside my list comprehension guard. Here is my code:
-- integer square root
isqrt :: Int -> Float
isqrt = sqrt . fromIntegral
-- hypotenuse
hyp :: Int -> Int -> Float
hyp x y = isqrt (x^2 + y^2)
-- pythagorean triplets in range [1..n]
pyths :: Int -> [(Int, Int, Int)]
pyths n = [(x, y, truncate (hyp x y)) | x <- [1..n], y <- [x..n], elem (hyp x y) [1..n]]
Here is the error:
• Couldn't match expected type ‘Float’ with actual type ‘Int’
• In the expression: n
In the second argument of ‘elem’, namely ‘[1 .. n]’
In the expression: elem (hyp x y) [1 .. n]
|
11 | pyths n = [(x, y, truncate (hyp x y)) | x <- [1..n], y <- [x..n], elem (hyp x y) [1..n]]
|
I can resolve the error by editing my guard from elem (hyp x y) [1..n] to elem (hyp x y) [1..fromIntegral n], which indicates to me that the variable n is somehow transformed from an Int to a Float at some point during the list comprehension.
The [1..fromIntegral n] doesn't look particularly concise or elegant compared to [1..5], is there another method that I should be using to either resolve or avoid this problem?