Here is my code:
sumOfSquare :: Int -> Int -> Int
sumOfSquare a b = a * a + b * b
hipotenuse :: Int -> Int -> Int
hipotenuse a b = truncate(sqrt(x))
where x = fromIntegral(sumOfSquare a b)
squareCheck :: Int -> Bool
squareCheck n = truncate(sqrt(x)) * truncate(sqrt(x)) == n
where x = fromIntegral n
isItSquare :: Int -> Int -> Bool
isItSquare a b = squareCheck (sumOfSquare a b)
data SidesType = Sides Int Int Int deriving (Show)
calc :: Int -> [SidesType]
calc a = [(Sides x y (hipotenuse x y)) | x <- [1..a], y <-[1..a], (isItSquare x y)]
test :: Int -> SidesType
test a = (Sides 1 2 3)
I need to display result of calc. It doesn’t work:
*Main> calc
<interactive>:1:0:
No instance for (Show (Int -> [SidesType]))
arising from a use of `print' at <interactive>:1:0-3
Possible fix:
add an instance declaration for (Show (Int -> [SidesType]))
In a stmt of an interactive GHCi command: print it
Call of test works correcly:
*Main> test 1
Sides 1 2 3
As I understanded the reason is the calc function return the list of SidesType and Haskell can display a SidesType, but cannot display the list of SidesType.
Do I need to change my SidesType description? Or do I need to fix error somehow else?
And another one question – can I display the result of calc function without defining new datatype:
calc :: Int -> (Int, Int, Int)
calc a = [x y (hipotenuse x y) | x <- [1..a], y <-[1..a], (isItSquare x y)]
?
Displaying the result of
calcis done just as you did with the result oftest:You tried to display the value of
calc, which you can’t do; there’s no representation of a function which can be printed (which should make sense—showis, at least by default, supposed to display something which can bereadback in, and you can’t do that with functions). If Haskell can display something, then it can display a list of something; there’s a declaration somewhere of(And there are similar instances for
Read,Eq, andOrd: lists of readable things are themselves readable, lists of things which can be compared for equality can themselves be compared for equality, and lists of things which can be ordered can themselves be ordered.)And yes, you can use a tuple instead of defining
SidesType:What you wrote—
x y (hipotenuse x y)—tries to call the functionxwith the two argumentsyandhipotenuse x y. Of course,xisn’t a function, so this can’t work. You need the commas and parentheses instead.Also, since you seem to be new to Haskell, here are a few small style points: people typically write
truncate $ sqrt xortruncate (sqrt x)instead oftruncate(sqrt(x)), and the parentheses aroundisItSquare x yandSides x y (hypotenuse x y)(which one could also writeSides x y $ hypotenuse x y) in the list comprehension are unnecessary. I’d also probably writedata Sides = Sides Int Int Int deriving (Eq,Show,Read)instead ofdata SidesType = Sides ..., but I’d really probably use(Int,Int,Int)instead, as you indicate you want to. And I’d probably give the functions a more generic type by replacingIntwith an instance ofIntegral; for instance,calc :: Integral i => i -> [(i,i,i)]. But this is more of a matter of taste.